aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/common/b2c2/flexcop.h2
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c3
-rw-r--r--drivers/media/common/siano/sms-cards.c6
-rw-r--r--drivers/media/common/siano/sms-cards.h1
-rw-r--r--drivers/media/common/siano/smscoreapi.c4
-rw-r--r--drivers/media/dvb-core/dmxdev.c7
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h2
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c45
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h2
-rw-r--r--drivers/media/dvb-core/dvb_ringbuffer.c26
-rw-r--r--drivers/media/dvb-core/dvb_ringbuffer.h2
-rw-r--r--drivers/media/dvb-frontends/Kconfig20
-rw-r--r--drivers/media/dvb-frontends/Makefile4
-rw-r--r--drivers/media/dvb-frontends/af9013.c24
-rw-r--r--drivers/media/dvb-frontends/af9033.c757
-rw-r--r--drivers/media/dvb-frontends/af9033.h58
-rw-r--r--drivers/media/dvb-frontends/af9033_priv.h1
-rw-r--r--drivers/media/dvb-frontends/as102_fe.c480
-rw-r--r--drivers/media/dvb-frontends/as102_fe.h29
-rw-r--r--drivers/media/dvb-frontends/as102_fe_types.h188
-rw-r--r--drivers/media/dvb-frontends/bcm3510.c6
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_c.c4
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_core.c4
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t.c4
-rw-r--r--drivers/media/dvb-frontends/dib7000p.c2
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c38
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c9
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c37
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.c101
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.h35
-rw-r--r--drivers/media/dvb-frontends/mb86a16.c6
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c14
-rw-r--r--drivers/media/dvb-frontends/mt312.c2
-rw-r--r--drivers/media/dvb-frontends/or51211.c2
-rw-r--r--drivers/media/dvb-frontends/rtl2832.c2
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.c118
-rw-r--r--drivers/media/dvb-frontends/si2165.c63
-rw-r--r--drivers/media/dvb-frontends/si2165_priv.h2
-rw-r--r--drivers/media/dvb-frontends/si2168.c129
-rw-r--r--drivers/media/dvb-frontends/si2168.h6
-rw-r--r--drivers/media/dvb-frontends/si2168_priv.h2
-rw-r--r--drivers/media/dvb-frontends/si21xx.c3
-rw-r--r--drivers/media/dvb-frontends/sp2.c441
-rw-r--r--drivers/media/dvb-frontends/sp2.h53
-rw-r--r--drivers/media/dvb-frontends/sp2_priv.h50
-rw-r--r--drivers/media/dvb-frontends/sp8870.c3
-rw-r--r--drivers/media/dvb-frontends/stv0367.c12
-rw-r--r--drivers/media/dvb-frontends/stv0900_core.c7
-rw-r--r--drivers/media/dvb-frontends/stv0900_sw.c3
-rw-r--r--drivers/media/dvb-frontends/tc90522.c840
-rw-r--r--drivers/media/dvb-frontends/tc90522.h42
-rw-r--r--drivers/media/dvb-frontends/tda10071.c2
-rw-r--r--drivers/media/dvb-frontends/zl10039.c2
-rw-r--r--drivers/media/firewire/firedtv-avc.c10
-rw-r--r--drivers/media/i2c/adv7343_regs.h2
-rw-r--r--drivers/media/i2c/adv7604.c2
-rw-r--r--drivers/media/i2c/adv7842.c4
-rw-r--r--drivers/media/i2c/cx25840/cx25840-ir.c2
-rw-r--r--drivers/media/i2c/lm3560.c4
-rw-r--r--drivers/media/i2c/ov7670.c14
-rw-r--r--drivers/media/i2c/s5k5baf.c2
-rw-r--r--drivers/media/i2c/saa6752hs.c6
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c143
-rw-r--r--drivers/media/i2c/smiapp/smiapp.h4
-rw-r--r--drivers/media/i2c/soc_camera/mt9t112.c4
-rw-r--r--drivers/media/i2c/soc_camera/ov772x.c5
-rw-r--r--drivers/media/i2c/soc_camera/ov9740.c4
-rw-r--r--drivers/media/i2c/tda7432.c2
-rw-r--r--drivers/media/i2c/tvp7002.c21
-rw-r--r--drivers/media/i2c/vs6624.c14
-rw-r--r--drivers/media/media-device.c6
-rw-r--r--drivers/media/media-devnode.c3
-rw-r--r--drivers/media/parport/pms.c7
-rw-r--r--drivers/media/pci/Kconfig2
-rw-r--r--drivers/media/pci/Makefile3
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c5
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.c4
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.c2
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.c6
-rw-r--r--drivers/media/pci/cx18/cx18-queue.c2
-rw-r--r--drivers/media/pci/cx23885/Kconfig9
-rw-r--r--drivers/media/pci/cx23885/Makefile1
-rw-r--r--drivers/media/pci/cx23885/altera-ci.c8
-rw-r--r--drivers/media/pci/cx23885/altera-ci.h4
-rw-r--r--drivers/media/pci/cx23885/cimax2.c4
-rw-r--r--drivers/media/pci/cx23885/cimax2.h4
-rw-r--r--drivers/media/pci/cx23885/cx23885-417.c503
-rw-r--r--drivers/media/pci/cx23885/cx23885-alsa.c109
-rw-r--r--drivers/media/pci/cx23885/cx23885-av.c5
-rw-r--r--drivers/media/pci/cx23885/cx23885-av.h5
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c32
-rw-r--r--drivers/media/pci/cx23885/cx23885-core.c362
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c323
-rw-r--r--drivers/media/pci/cx23885/cx23885-f300.c4
-rw-r--r--drivers/media/pci/cx23885/cx23885-i2c.c12
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.c5
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.h5
-rw-r--r--drivers/media/pci/cx23885/cx23885-ioctl.c10
-rw-r--r--drivers/media/pci/cx23885/cx23885-ioctl.h4
-rw-r--r--drivers/media/pci/cx23885/cx23885-ir.c5
-rw-r--r--drivers/media/pci/cx23885/cx23885-ir.h5
-rw-r--r--drivers/media/pci/cx23885/cx23885-reg.h4
-rw-r--r--drivers/media/pci/cx23885/cx23885-vbi.c284
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c1294
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.h5
-rw-r--r--drivers/media/pci/cx23885/cx23885.h136
-rw-r--r--drivers/media/pci/cx23885/cx23888-ir.c7
-rw-r--r--drivers/media/pci/cx23885/cx23888-ir.h5
-rw-r--r--drivers/media/pci/cx23885/netup-eeprom.c4
-rw-r--r--drivers/media/pci/cx23885/netup-eeprom.h4
-rw-r--r--drivers/media/pci/cx23885/netup-init.c4
-rw-r--r--drivers/media/pci/cx23885/netup-init.h4
-rw-r--r--drivers/media/pci/cx25821/cx25821-video-upstream.c5
-rw-r--r--drivers/media/pci/cx88/cx88-cards.c632
-rw-r--r--drivers/media/pci/cx88/cx88-video.c3
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-core.c30
-rw-r--r--drivers/media/pci/ddbridge/ddbridge.h12
-rw-r--r--drivers/media/pci/dm1105/dm1105.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-pcm.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-firmware.c4
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.c12
-rw-r--r--drivers/media/pci/mantis/hopper_vp3028.c2
-rw-r--r--drivers/media/pci/mantis/mantis_common.h2
-rw-r--r--drivers/media/pci/mantis/mantis_vp1033.c4
-rw-r--r--drivers/media/pci/mantis/mantis_vp1034.c2
-rw-r--r--drivers/media/pci/mantis/mantis_vp1041.c4
-rw-r--r--drivers/media/pci/mantis/mantis_vp2033.c4
-rw-r--r--drivers/media/pci/mantis/mantis_vp2040.c4
-rw-r--r--drivers/media/pci/mantis/mantis_vp3030.c4
-rw-r--r--drivers/media/pci/ngene/ngene-cards.c2
-rw-r--r--drivers/media/pci/ngene/ngene-core.c14
-rw-r--r--drivers/media/pci/ngene/ngene-dvb.c7
-rw-r--r--drivers/media/pci/ngene/ngene.h2
-rw-r--r--drivers/media/pci/pt3/Kconfig10
-rw-r--r--drivers/media/pci/pt3/Makefile8
-rw-r--r--drivers/media/pci/pt3/pt3.c876
-rw-r--r--drivers/media/pci/pt3/pt3.h186
-rw-r--r--drivers/media/pci/pt3/pt3_dma.c225
-rw-r--r--drivers/media/pci/pt3/pt3_i2c.c240
-rw-r--r--drivers/media/pci/saa7134/Kconfig8
-rw-r--r--drivers/media/pci/saa7134/Makefile2
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c29
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c10
-rw-r--r--drivers/media/pci/saa7134/saa7134-go7007.c531
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134.h5
-rw-r--r--drivers/media/pci/saa7164/saa7164-api.c3
-rw-r--r--drivers/media/pci/saa7164/saa7164-core.c6
-rw-r--r--drivers/media/pci/solo6x10/Kconfig1
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-disp.c4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-eeprom.c8
-rw-r--r--drivers/media/pci/solo6x10/solo6x10.h4
-rw-r--r--drivers/media/pci/sta2x11/Kconfig1
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c2
-rw-r--r--drivers/media/pci/ttpci/Kconfig4
-rw-r--r--drivers/media/pci/ttpci/Makefile2
-rw-r--r--drivers/media/pci/ttpci/av7110.c8
-rw-r--r--drivers/media/pci/tw68/Kconfig10
-rw-r--r--drivers/media/pci/tw68/Makefile3
-rw-r--r--drivers/media/pci/tw68/tw68-core.c434
-rw-r--r--drivers/media/pci/tw68/tw68-reg.h195
-rw-r--r--drivers/media/pci/tw68/tw68-risc.c230
-rw-r--r--drivers/media/pci/tw68/tw68-video.c1051
-rw-r--r--drivers/media/pci/tw68/tw68.h231
-rw-r--r--drivers/media/pci/zoran/zoran_device.c2
-rw-r--r--drivers/media/platform/Kconfig54
-rw-r--r--drivers/media/platform/Makefile8
-rw-r--r--drivers/media/platform/blackfin/Kconfig1
-rw-r--r--drivers/media/platform/coda.c3933
-rw-r--r--drivers/media/platform/coda/Makefile3
-rw-r--r--drivers/media/platform/coda/coda-bit.c1861
-rw-r--r--drivers/media/platform/coda/coda-common.c2052
-rw-r--r--drivers/media/platform/coda/coda-h264.c37
-rw-r--r--drivers/media/platform/coda/coda.h287
-rw-r--r--drivers/media/platform/coda/coda_regs.h (renamed from drivers/media/platform/coda.h)0
-rw-r--r--drivers/media/platform/davinci/Kconfig18
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc.c2
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc.c14
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c16
-rw-r--r--drivers/media/platform/davinci/vpif.c1
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c13
-rw-r--r--drivers/media/platform/davinci/vpif_display.c22
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.c6
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-m2m.c3
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-regs.c8
-rw-r--r--drivers/media/platform/exynos4-is/Kconfig5
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-errno.c4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-errno.h4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-param.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.c10
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp-video.c9
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c4
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c3
-rw-r--r--drivers/media/platform/marvell-ccic/Kconfig2
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.c2
-rw-r--r--drivers/media/platform/mx2_emmaprp.c2
-rw-r--r--drivers/media/platform/omap/Kconfig2
-rw-r--r--drivers/media/platform/omap/omap_vout.c16
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.c10
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.h18
-rw-r--r--drivers/media/platform/omap3isp/cfa_coef_table.h10
-rw-r--r--drivers/media/platform/omap3isp/gamma_table.h10
-rw-r--r--drivers/media/platform/omap3isp/isp.c20
-rw-r--r--drivers/media/platform/omap3isp/isp.h10
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c424
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.h21
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.c10
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.h10
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.c10
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.h10
-rw-r--r--drivers/media/platform/omap3isp/ispcsiphy.c10
-rw-r--r--drivers/media/platform/omap3isp/ispcsiphy.h10
-rw-r--r--drivers/media/platform/omap3isp/isph3a.h10
-rw-r--r--drivers/media/platform/omap3isp/isph3a_aewb.c10
-rw-r--r--drivers/media/platform/omap3isp/isph3a_af.c10
-rw-r--r--drivers/media/platform/omap3isp/isphist.c10
-rw-r--r--drivers/media/platform/omap3isp/isphist.h10
-rw-r--r--drivers/media/platform/omap3isp/isppreview.c10
-rw-r--r--drivers/media/platform/omap3isp/isppreview.h10
-rw-r--r--drivers/media/platform/omap3isp/ispreg.h20
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.c80
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.h13
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c10
-rw-r--r--drivers/media/platform/omap3isp/ispstat.h10
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c59
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.h12
-rw-r--r--drivers/media/platform/omap3isp/luma_enhance_table.h10
-rw-r--r--drivers/media/platform/omap3isp/noise_filter_table.h10
-rw-r--r--drivers/media/platform/s3c-camif/camif-capture.c4
-rw-r--r--drivers/media/platform/s3c-camif/camif-regs.c4
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c7
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c11
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c6
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c83
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h6
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c27
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_debug.h6
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c54
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c67
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.c4
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.h488
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c31
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c491
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.c2
-rw-r--r--drivers/media/platform/s5p-tv/Kconfig4
-rw-r--r--drivers/media/platform/s5p-tv/hdmi_drv.c2
-rw-r--r--drivers/media/platform/s5p-tv/sdo_drv.c2
-rw-r--r--drivers/media/platform/s5p-tv/sii9234_drv.c2
-rw-r--r--drivers/media/platform/sh_veu.c4
-rw-r--r--drivers/media/platform/soc_camera/Kconfig16
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c13
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c5
-rw-r--r--drivers/media/platform/soc_camera/pxa_camera.c2
-rw-r--r--drivers/media/platform/soc_camera/rcar_vin.c4
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c21
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.c4
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c20
-rw-r--r--drivers/media/platform/via-camera.c13
-rw-r--r--drivers/media/platform/vivi.c1542
-rw-r--r--drivers/media/platform/vivid/Kconfig19
-rw-r--r--drivers/media/platform/vivid/Makefile6
-rw-r--r--drivers/media/platform/vivid/vivid-core.c1390
-rw-r--r--drivers/media/platform/vivid/vivid-core.h520
-rw-r--r--drivers/media/platform/vivid/vivid-ctrls.c1502
-rw-r--r--drivers/media/platform/vivid/vivid-ctrls.h34
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-cap.c886
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-cap.h26
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-out.c305
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-out.h26
-rw-r--r--drivers/media/platform/vivid/vivid-osd.c400
-rw-r--r--drivers/media/platform/vivid/vivid-osd.h27
-rw-r--r--drivers/media/platform/vivid/vivid-radio-common.c189
-rw-r--r--drivers/media/platform/vivid/vivid-radio-common.h40
-rw-r--r--drivers/media/platform/vivid/vivid-radio-rx.c287
-rw-r--r--drivers/media/platform/vivid/vivid-radio-rx.h31
-rw-r--r--drivers/media/platform/vivid/vivid-radio-tx.c141
-rw-r--r--drivers/media/platform/vivid/vivid-radio-tx.h29
-rw-r--r--drivers/media/platform/vivid/vivid-rds-gen.c166
-rw-r--r--drivers/media/platform/vivid/vivid-rds-gen.h53
-rw-r--r--drivers/media/platform/vivid/vivid-sdr-cap.c499
-rw-r--r--drivers/media/platform/vivid/vivid-sdr-cap.h34
-rw-r--r--drivers/media/platform/vivid/vivid-tpg-colors.c310
-rw-r--r--drivers/media/platform/vivid/vivid-tpg-colors.h64
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.c1439
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.h439
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-cap.c371
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-cap.h40
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-gen.c323
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-gen.h33
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-out.c248
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-out.h34
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c1730
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.h71
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c571
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.h61
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.c1146
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.h56
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c6
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c4
-rw-r--r--drivers/media/radio/radio-tea5764.c12
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c4
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c4
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c11
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.c10
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.c2
-rw-r--r--drivers/media/rc/Kconfig15
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/ene_ir.c2
-rw-r--r--drivers/media/rc/fintek-cir.c6
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.c6
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.h6
-rw-r--r--drivers/media/rc/imon.c304
-rw-r--r--drivers/media/rc/ir-hix5hd2.c351
-rw-r--r--drivers/media/rc/ite-cir.c3
-rw-r--r--drivers/media/rc/keymaps/Makefile1
-rw-r--r--drivers/media/rc/keymaps/rc-dvbsky.c78
-rw-r--r--drivers/media/rc/lirc_dev.c14
-rw-r--r--drivers/media/rc/mceusb.c15
-rw-r--r--drivers/media/rc/nuvoton-cir.c6
-rw-r--r--drivers/media/rc/st_rc.c16
-rw-r--r--drivers/media/rc/streamzap.c6
-rw-r--r--drivers/media/tuners/Kconfig17
-rw-r--r--drivers/media/tuners/Makefile4
-rw-r--r--drivers/media/tuners/e4000.c75
-rw-r--r--drivers/media/tuners/it913x.c478
-rw-r--r--drivers/media/tuners/it913x.h (renamed from drivers/media/tuners/tuner_it913x.h)41
-rw-r--r--drivers/media/tuners/m88ts2022.c355
-rw-r--r--drivers/media/tuners/m88ts2022_priv.h5
-rw-r--r--drivers/media/tuners/msi001.c56
-rw-r--r--drivers/media/tuners/mt2060.c3
-rw-r--r--drivers/media/tuners/mt2063.c26
-rw-r--r--drivers/media/tuners/mxl301rf.c349
-rw-r--r--drivers/media/tuners/mxl301rf.h26
-rw-r--r--drivers/media/tuners/mxl5005s.c3
-rw-r--r--drivers/media/tuners/qm1d1c0042.c448
-rw-r--r--drivers/media/tuners/qm1d1c0042.h37
-rw-r--r--drivers/media/tuners/si2157.c86
-rw-r--r--drivers/media/tuners/si2157.h2
-rw-r--r--drivers/media/tuners/si2157_priv.h3
-rw-r--r--drivers/media/tuners/tda18212.c272
-rw-r--r--drivers/media/tuners/tda18212.h19
-rw-r--r--drivers/media/tuners/tda18271-common.c19
-rw-r--r--drivers/media/tuners/tda18271-priv.h4
-rw-r--r--drivers/media/tuners/tuner-xc2028.c62
-rw-r--r--drivers/media/tuners/tuner_it913x.c453
-rw-r--r--drivers/media/tuners/tuner_it913x_priv.h78
-rw-r--r--drivers/media/tuners/xc4000.c62
-rw-r--r--drivers/media/tuners/xc5000.c242
-rw-r--r--drivers/media/usb/Kconfig4
-rw-r--r--drivers/media/usb/Makefile4
-rw-r--r--drivers/media/usb/airspy/airspy.c222
-rw-r--r--drivers/media/usb/as102/Kconfig8
-rw-r--r--drivers/media/usb/as102/Makefile7
-rw-r--r--drivers/media/usb/as102/as102_drv.c401
-rw-r--r--drivers/media/usb/as102/as102_drv.h83
-rw-r--r--drivers/media/usb/as102/as102_fw.c228
-rw-r--r--drivers/media/usb/as102/as102_fw.h34
-rw-r--r--drivers/media/usb/as102/as102_usb_drv.c475
-rw-r--r--drivers/media/usb/as102/as102_usb_drv.h57
-rw-r--r--drivers/media/usb/as102/as10x_cmd.c413
-rw-r--r--drivers/media/usb/as102/as10x_cmd.h523
-rw-r--r--drivers/media/usb/as102/as10x_cmd_cfg.c201
-rw-r--r--drivers/media/usb/as102/as10x_cmd_stream.c207
-rw-r--r--drivers/media/usb/as102/as10x_handle.h51
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c36
-rw-r--r--drivers/media/usb/au0828/au0828-core.c84
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c110
-rw-r--r--drivers/media/usb/au0828/au0828-i2c.c15
-rw-r--r--drivers/media/usb/au0828/au0828-input.c36
-rw-r--r--drivers/media/usb/au0828/au0828-vbi.c4
-rw-r--r--drivers/media/usb/au0828/au0828-video.c90
-rw-r--r--drivers/media/usb/au0828/au0828.h34
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-avcore.c14
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c10
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-core.c2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c8
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig7
-rw-r--r--drivers/media/usb/dvb-usb-v2/Makefile3
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c644
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.h12
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c185
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.h3
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h3
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c28
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvbsky.c460
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c8
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig2
-rw-r--r--drivers/media/usb/dvb-usb/af9005.c2
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c130
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h4
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c383
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-common.c12
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c14
-rw-r--r--drivers/media/usb/dvb-usb/opera1.c4
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c8
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c10
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c43
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c47
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c37
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c29
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c11
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c29
-rw-r--r--drivers/media/usb/em28xx/em28xx.h19
-rw-r--r--drivers/media/usb/go7007/go7007-usb.c4
-rw-r--r--drivers/media/usb/gspca/gspca.c5
-rw-r--r--drivers/media/usb/gspca/gspca.h2
-rw-r--r--drivers/media/usb/gspca/kinect.c12
-rw-r--r--drivers/media/usb/gspca/sn9c20x.c12
-rw-r--r--drivers/media/usb/hackrf/Kconfig10
-rw-r--r--drivers/media/usb/hackrf/Makefile1
-rw-r--r--drivers/media/usb/hackrf/hackrf.c1142
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-control.c21
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-core.c27
-rw-r--r--drivers/media/usb/msi2500/msi2500.c174
-rw-r--r--drivers/media/usb/pwc/pwc-v4l.c2
-rw-r--r--drivers/media/usb/s2255/s2255drv.c2
-rw-r--r--drivers/media/usb/siano/smsusb.c6
-rw-r--r--drivers/media/usb/ttusb-dec/ttusbdecfe.c3
-rw-r--r--drivers/media/usb/usbtv/Kconfig3
-rw-r--r--drivers/media/usb/usbtv/Makefile3
-rw-r--r--drivers/media/usb/usbtv/usbtv-audio.c385
-rw-r--r--drivers/media/usb/usbtv/usbtv-core.c17
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c18
-rw-r--r--drivers/media/usb/usbtv/usbtv.h21
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c60
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c20
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c1
-rw-r--r--drivers/media/usb/uvc/uvc_video.c10
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h5
-rw-r--r--drivers/media/v4l2-core/tuner-core.c10
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c9
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c30
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c6
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c3
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c6
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c9
-rw-r--r--drivers/media/v4l2-core/videobuf-core.c11
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-sg.c6
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c66
448 files changed, 37490 insertions, 12268 deletions
diff --git a/drivers/media/common/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h
index 897b10c..8942bda 100644
--- a/drivers/media/common/b2c2/flexcop.h
+++ b/drivers/media/common/b2c2/flexcop.h
@@ -4,7 +4,7 @@
* see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_H__
-#define __FLEXCOP_H___
+#define __FLEXCOP_H__
#define FC_LOG_PREFIX "b2c2-flexcop"
#include "flexcop-common.h"
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index 6c47f3f..b7d6393 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -311,7 +311,6 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
}
default:
BUG();
- return 0;
}
if (mutex_lock_interruptible(vdev->lock))
@@ -399,7 +398,6 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
return -EINVAL;
default:
BUG();
- return 0;
}
}
@@ -423,7 +421,6 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou
return -EINVAL;
default:
BUG();
- return -EINVAL;
}
}
diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c
index 8276999..82c7a12 100644
--- a/drivers/media/common/siano/sms-cards.c
+++ b/drivers/media/common/siano/sms-cards.c
@@ -157,6 +157,12 @@ static struct sms_board sms_boards[] = {
.type = SMS_DENVER_2160,
.default_mode = DEVICE_MODE_DAB_TDMB,
},
+ [SMS1XXX_BOARD_PCTV_77E] = {
+ .name = "Hauppauge microStick 77e",
+ .type = SMS_NOVA_B0,
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ_B0,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
+ },
};
struct sms_board *sms_get_board(unsigned id)
diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h
index c63b544..4c4cadd 100644
--- a/drivers/media/common/siano/sms-cards.h
+++ b/drivers/media/common/siano/sms-cards.h
@@ -45,6 +45,7 @@
#define SMS1XXX_BOARD_SIANO_RIO 18
#define SMS1XXX_BOARD_SIANO_DENVER_1530 19
#define SMS1XXX_BOARD_SIANO_DENVER_2160 20
+#define SMS1XXX_BOARD_PCTV_77E 21
struct sms_board_gpio_cfg {
int lna_vhf_exist;
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 050984c..a367743 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -2129,8 +2129,6 @@ int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
static int __init smscore_module_init(void)
{
- int rc = 0;
-
INIT_LIST_HEAD(&g_smscore_notifyees);
INIT_LIST_HEAD(&g_smscore_devices);
kmutex_init(&g_smscore_deviceslock);
@@ -2138,7 +2136,7 @@ static int __init smscore_module_init(void)
INIT_LIST_HEAD(&g_smscore_registry);
kmutex_init(&g_smscore_registrylock);
- return rc;
+ return 0;
}
static void __exit smscore_module_exit(void)
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index c0363f1..abff803 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -1087,8 +1087,8 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
struct dmxdev_filter *dmxdevfilter = file->private_data;
unsigned int mask = 0;
- if (!dmxdevfilter)
- return -EINVAL;
+ if ((!dmxdevfilter) || dmxdevfilter->dev->exit)
+ return POLLERR;
poll_wait(file, &dmxdevfilter->buffer.queue, wait);
@@ -1181,6 +1181,9 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
dprintk("function : %s\n", __func__);
+ if (dmxdev->exit)
+ return POLLERR;
+
poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 12ce19c..e07a84e 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -144,6 +144,7 @@
#define USB_PID_ITETECH_IT9135 0x9135
#define USB_PID_ITETECH_IT9135_9005 0x9005
#define USB_PID_ITETECH_IT9135_9006 0x9006
+#define USB_PID_ITETECH_IT9303 0x9306
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_399U_2 0xe400
#define USB_PID_KWORLD_395U 0xe396
@@ -244,6 +245,7 @@
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
+#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index c2a6a0a..b8579ee 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -1934,15 +1934,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int err = 0;
- struct dtv_properties *tvps = NULL;
+ struct dtv_properties *tvps = parg;
struct dtv_property *tvp = NULL;
int i;
dev_dbg(fe->dvb->device, "%s:\n", __func__);
- if(cmd == FE_SET_PROPERTY) {
- tvps = (struct dtv_properties __user *)parg;
-
+ if (cmd == FE_SET_PROPERTY) {
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
@@ -1957,7 +1955,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
goto out;
}
- if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
+ if (copy_from_user(tvp, (void __user *)tvps->props,
+ tvps->num * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
@@ -1972,10 +1971,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
if (c->state == DTV_TUNE)
dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
- } else
- if(cmd == FE_GET_PROPERTY) {
- tvps = (struct dtv_properties __user *)parg;
-
+ } else if (cmd == FE_GET_PROPERTY) {
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
@@ -1990,7 +1986,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
goto out;
}
- if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
+ if (copy_from_user(tvp, (void __user *)tvps->props,
+ tvps->num * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
@@ -2012,7 +2009,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
(tvp + i)->result = err;
}
- if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
+ if (copy_to_user((void __user *)tvps->props, tvp,
+ tvps->num * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
@@ -2072,6 +2070,23 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
case SYS_DVBC_ANNEX_C:
rolloff = 113;
break;
+ case SYS_DVBS:
+ case SYS_TURBO:
+ rolloff = 135;
+ break;
+ case SYS_DVBS2:
+ switch (c->rolloff) {
+ case ROLLOFF_20:
+ rolloff = 120;
+ break;
+ case ROLLOFF_25:
+ rolloff = 125;
+ break;
+ default:
+ case ROLLOFF_35:
+ rolloff = 135;
+ }
+ break;
default:
break;
}
@@ -2550,7 +2565,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
fe->id);
- if (fe->ops.tuner_ops.sleep)
+ if (fe->ops.tuner_ops.suspend)
+ ret = fe->ops.tuner_ops.suspend(fe);
+ else if (fe->ops.tuner_ops.sleep)
ret = fe->ops.tuner_ops.sleep(fe);
if (fe->ops.sleep)
@@ -2572,7 +2589,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
if (fe->ops.init)
ret = fe->ops.init(fe);
- if (fe->ops.tuner_ops.init)
+ if (fe->ops.tuner_ops.resume)
+ ret = fe->ops.tuner_ops.resume(fe);
+ else if (fe->ops.tuner_ops.init)
ret = fe->ops.tuner_ops.init(fe);
fe->exit = DVB_FE_NO_EXIT;
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index d398de4..816269e 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -201,6 +201,8 @@ struct dvb_tuner_ops {
int (*release)(struct dvb_frontend *fe);
int (*init)(struct dvb_frontend *fe);
int (*sleep)(struct dvb_frontend *fe);
+ int (*suspend)(struct dvb_frontend *fe);
+ int (*resume)(struct dvb_frontend *fe);
/** This is for simple PLLs - set all parameters in one go. */
int (*set_params)(struct dvb_frontend *fe);
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c
index a5712cd..1100e98 100644
--- a/drivers/media/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
@@ -166,6 +166,31 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t
return len;
}
+ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+ const u8 __user *buf, size_t len)
+{
+ int status;
+ size_t todo = len;
+ size_t split;
+
+ split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
+
+ if (split > 0) {
+ status = copy_from_user(rbuf->data+rbuf->pwrite, buf, split);
+ if (status)
+ return len - todo;
+ buf += split;
+ todo -= split;
+ rbuf->pwrite = 0;
+ }
+ status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo);
+ if (status)
+ return len - todo;
+ rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
+
+ return len;
+}
+
ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
{
int status;
@@ -297,3 +322,4 @@ EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
EXPORT_SYMBOL(dvb_ringbuffer_read_user);
EXPORT_SYMBOL(dvb_ringbuffer_read);
EXPORT_SYMBOL(dvb_ringbuffer_write);
+EXPORT_SYMBOL(dvb_ringbuffer_write_user);
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h
index 41f04da..9e1e11b 100644
--- a/drivers/media/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb-core/dvb_ringbuffer.h
@@ -133,6 +133,8 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
*/
extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
size_t len);
+extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+ const u8 __user *buf, size_t len);
/**
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index fe0ddcc..5a13454 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -471,6 +471,11 @@ config DVB_SI2168
help
Say Y when you want to support this frontend.
+config DVB_AS102_FE
+ tristate
+ depends on DVB_CORE
+ default DVB_AS102
+
comment "DVB-C (cable) frontends"
depends on DVB_CORE
@@ -643,6 +648,14 @@ config DVB_MB86A20S
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
+config DVB_TC90522
+ tristate "Toshiba TC90522"
+ depends on DVB_CORE && I2C
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ A Toshiba TC90522 2xISDB-T + 2xISDB-S demodulator.
+ Say Y when you want to support this frontend.
+
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
@@ -720,6 +733,13 @@ config DVB_A8293
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
+config DVB_SP2
+ tristate "CIMaX SP2"
+ depends on DVB_CORE && I2C
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ CIMaX SP2/SP2HF Common Interface module.
+
config DVB_LGS8GL5
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
depends on DVB_CORE && I2C
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index edf103d..ba59df6 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -107,10 +107,12 @@ obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_SI2165) += si2165.o
obj-$(CONFIG_DVB_A8293) += a8293.o
+obj-$(CONFIG_DVB_SP2) += sp2.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o
-
+obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
+obj-$(CONFIG_DVB_TC90522) += tc90522.o
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
index ecf6388..8001690 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -683,7 +683,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
switch (c->transmission_mode) {
case TRANSMISSION_MODE_AUTO:
- auto_mode = 1;
+ auto_mode = true;
break;
case TRANSMISSION_MODE_2K:
break;
@@ -693,12 +693,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid transmission_mode\n",
__func__);
- auto_mode = 1;
+ auto_mode = true;
}
switch (c->guard_interval) {
case GUARD_INTERVAL_AUTO:
- auto_mode = 1;
+ auto_mode = true;
break;
case GUARD_INTERVAL_1_32:
break;
@@ -714,12 +714,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid guard_interval\n",
__func__);
- auto_mode = 1;
+ auto_mode = true;
}
switch (c->hierarchy) {
case HIERARCHY_AUTO:
- auto_mode = 1;
+ auto_mode = true;
break;
case HIERARCHY_NONE:
break;
@@ -734,12 +734,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
break;
default:
dev_dbg(&state->i2c->dev, "%s: invalid hierarchy\n", __func__);
- auto_mode = 1;
+ auto_mode = true;
}
switch (c->modulation) {
case QAM_AUTO:
- auto_mode = 1;
+ auto_mode = true;
break;
case QPSK:
break;
@@ -751,7 +751,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
break;
default:
dev_dbg(&state->i2c->dev, "%s: invalid modulation\n", __func__);
- auto_mode = 1;
+ auto_mode = true;
}
/* Use HP. How and which case we can switch to LP? */
@@ -759,7 +759,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
switch (c->code_rate_HP) {
case FEC_AUTO:
- auto_mode = 1;
+ auto_mode = true;
break;
case FEC_1_2:
break;
@@ -778,12 +778,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid code_rate_HP\n",
__func__);
- auto_mode = 1;
+ auto_mode = true;
}
switch (c->code_rate_LP) {
case FEC_AUTO:
- auto_mode = 1;
+ auto_mode = true;
break;
case FEC_1_2:
break;
@@ -804,7 +804,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid code_rate_LP\n",
__func__);
- auto_mode = 1;
+ auto_mode = true;
}
switch (c->bandwidth_hz) {
diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
index 5c90ea6..63a89c1 100644
--- a/drivers/media/dvb-frontends/af9033.c
+++ b/drivers/media/dvb-frontends/af9033.c
@@ -24,29 +24,35 @@
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE 64
-struct af9033_state {
- struct i2c_adapter *i2c;
+struct af9033_dev {
+ struct i2c_client *client;
struct dvb_frontend fe;
struct af9033_config cfg;
+ bool is_af9035;
+ bool is_it9135;
u32 bandwidth_hz;
bool ts_mode_parallel;
bool ts_mode_serial;
- u32 ber;
- u32 ucb;
- unsigned long last_stat_check;
+ fe_status_t fe_status;
+ u64 post_bit_error_prev; /* for old read_ber we return (curr - prev) */
+ u64 post_bit_error;
+ u64 post_bit_count;
+ u64 error_block_count;
+ u64 total_block_count;
+ struct delayed_work stat_work;
};
/* write multiple registers */
-static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
+static int af9033_wr_regs(struct af9033_dev *dev, u32 reg, const u8 *val,
int len)
{
int ret;
u8 buf[MAX_XFER_SIZE];
struct i2c_msg msg[1] = {
{
- .addr = state->cfg.i2c_addr,
+ .addr = dev->client->addr,
.flags = 0,
.len = 3 + len,
.buf = buf,
@@ -54,9 +60,9 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
};
if (3 + len > sizeof(buf)) {
- dev_warn(&state->i2c->dev,
- "%s: i2c wr reg=%04x: len=%d is too big!\n",
- KBUILD_MODNAME, reg, len);
+ dev_warn(&dev->client->dev,
+ "i2c wr reg=%04x: len=%d is too big!\n",
+ reg, len);
return -EINVAL;
}
@@ -65,12 +71,12 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
buf[2] = (reg >> 0) & 0xff;
memcpy(&buf[3], val, len);
- ret = i2c_transfer(state->i2c, msg, 1);
+ ret = i2c_transfer(dev->client->adapter, msg, 1);
if (ret == 1) {
ret = 0;
} else {
- dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%06x " \
- "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ dev_warn(&dev->client->dev, "i2c wr failed=%d reg=%06x len=%d\n",
+ ret, reg, len);
ret = -EREMOTEIO;
}
@@ -78,31 +84,31 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
}
/* read multiple registers */
-static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
+static int af9033_rd_regs(struct af9033_dev *dev, u32 reg, u8 *val, int len)
{
int ret;
u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
(reg >> 0) & 0xff };
struct i2c_msg msg[2] = {
{
- .addr = state->cfg.i2c_addr,
+ .addr = dev->client->addr,
.flags = 0,
.len = sizeof(buf),
.buf = buf
}, {
- .addr = state->cfg.i2c_addr,
+ .addr = dev->client->addr,
.flags = I2C_M_RD,
.len = len,
.buf = val
}
};
- ret = i2c_transfer(state->i2c, msg, 2);
+ ret = i2c_transfer(dev->client->adapter, msg, 2);
if (ret == 2) {
ret = 0;
} else {
- dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%06x " \
- "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ dev_warn(&dev->client->dev, "i2c rd failed=%d reg=%06x len=%d\n",
+ ret, reg, len);
ret = -EREMOTEIO;
}
@@ -111,19 +117,19 @@ static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
/* write single register */
-static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val)
+static int af9033_wr_reg(struct af9033_dev *dev, u32 reg, u8 val)
{
- return af9033_wr_regs(state, reg, &val, 1);
+ return af9033_wr_regs(dev, reg, &val, 1);
}
/* read single register */
-static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val)
+static int af9033_rd_reg(struct af9033_dev *dev, u32 reg, u8 *val)
{
- return af9033_rd_regs(state, reg, val, 1);
+ return af9033_rd_regs(dev, reg, val, 1);
}
/* write single register with mask */
-static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
+static int af9033_wr_reg_mask(struct af9033_dev *dev, u32 reg, u8 val,
u8 mask)
{
int ret;
@@ -131,7 +137,7 @@ static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
/* no need for read if whole reg is written */
if (mask != 0xff) {
- ret = af9033_rd_regs(state, reg, &tmp, 1);
+ ret = af9033_rd_regs(dev, reg, &tmp, 1);
if (ret)
return ret;
@@ -140,17 +146,17 @@ static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
val |= tmp;
}
- return af9033_wr_regs(state, reg, &val, 1);
+ return af9033_wr_regs(dev, reg, &val, 1);
}
/* read single register with mask */
-static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
+static int af9033_rd_reg_mask(struct af9033_dev *dev, u32 reg, u8 *val,
u8 mask)
{
int ret, i;
u8 tmp;
- ret = af9033_rd_regs(state, reg, &tmp, 1);
+ ret = af9033_rd_regs(dev, reg, &tmp, 1);
if (ret)
return ret;
@@ -167,18 +173,17 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
}
/* write reg val table using reg addr auto increment */
-static int af9033_wr_reg_val_tab(struct af9033_state *state,
+static int af9033_wr_reg_val_tab(struct af9033_dev *dev,
const struct reg_val *tab, int tab_len)
{
#define MAX_TAB_LEN 212
int ret, i, j;
u8 buf[1 + MAX_TAB_LEN];
- dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
+ dev_dbg(&dev->client->dev, "tab_len=%d\n", tab_len);
if (tab_len > sizeof(buf)) {
- dev_warn(&state->i2c->dev, "%s: tab len %d is too big\n",
- KBUILD_MODNAME, tab_len);
+ dev_warn(&dev->client->dev, "tab len %d is too big\n", tab_len);
return -EINVAL;
}
@@ -186,7 +191,7 @@ static int af9033_wr_reg_val_tab(struct af9033_state *state,
buf[j] = tab[i].val;
if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
- ret = af9033_wr_regs(state, tab[i].reg - j, buf, j + 1);
+ ret = af9033_wr_regs(dev, tab[i].reg - j, buf, j + 1);
if (ret < 0)
goto err;
@@ -199,16 +204,16 @@ static int af9033_wr_reg_val_tab(struct af9033_state *state,
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
-static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
+static u32 af9033_div(struct af9033_dev *dev, u32 a, u32 b, u32 x)
{
u32 r = 0, c = 0, i;
- dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d\n", __func__, a, b, x);
+ dev_dbg(&dev->client->dev, "a=%d b=%d x=%d\n", a, b, x);
if (a > b) {
c = a / b;
@@ -225,22 +230,15 @@ static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
}
r = (c << (u32)x) + r;
- dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d r=%d r=%x\n",
- __func__, a, b, x, r, r);
+ dev_dbg(&dev->client->dev, "a=%d b=%d x=%d r=%d r=%x\n", a, b, x, r, r);
return r;
}
-static void af9033_release(struct dvb_frontend *fe)
-{
- struct af9033_state *state = fe->demodulator_priv;
-
- kfree(state);
-}
-
static int af9033_init(struct dvb_frontend *fe)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i, len;
const struct reg_val *init;
u8 buf[4];
@@ -248,7 +246,7 @@ static int af9033_init(struct dvb_frontend *fe)
struct reg_val_mask tab[] = {
{ 0x80fb24, 0x00, 0x08 },
{ 0x80004c, 0x00, 0xff },
- { 0x00f641, state->cfg.tuner, 0xff },
+ { 0x00f641, dev->cfg.tuner, 0xff },
{ 0x80f5ca, 0x01, 0x01 },
{ 0x80f715, 0x01, 0x01 },
{ 0x00f41f, 0x04, 0x04 },
@@ -267,88 +265,82 @@ static int af9033_init(struct dvb_frontend *fe)
{ 0x00d830, 0x01, 0xff },
{ 0x00d831, 0x00, 0xff },
{ 0x00d832, 0x00, 0xff },
- { 0x80f985, state->ts_mode_serial, 0x01 },
- { 0x80f986, state->ts_mode_parallel, 0x01 },
+ { 0x80f985, dev->ts_mode_serial, 0x01 },
+ { 0x80f986, dev->ts_mode_parallel, 0x01 },
{ 0x00d827, 0x00, 0xff },
{ 0x00d829, 0x00, 0xff },
- { 0x800045, state->cfg.adc_multiplier, 0xff },
+ { 0x800045, dev->cfg.adc_multiplier, 0xff },
};
/* program clock control */
- clock_cw = af9033_div(state, state->cfg.clock, 1000000ul, 19ul);
+ clock_cw = af9033_div(dev, dev->cfg.clock, 1000000ul, 19ul);
buf[0] = (clock_cw >> 0) & 0xff;
buf[1] = (clock_cw >> 8) & 0xff;
buf[2] = (clock_cw >> 16) & 0xff;
buf[3] = (clock_cw >> 24) & 0xff;
- dev_dbg(&state->i2c->dev, "%s: clock=%d clock_cw=%08x\n",
- __func__, state->cfg.clock, clock_cw);
+ dev_dbg(&dev->client->dev, "clock=%d clock_cw=%08x\n",
+ dev->cfg.clock, clock_cw);
- ret = af9033_wr_regs(state, 0x800025, buf, 4);
+ ret = af9033_wr_regs(dev, 0x800025, buf, 4);
if (ret < 0)
goto err;
/* program ADC control */
for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
- if (clock_adc_lut[i].clock == state->cfg.clock)
+ if (clock_adc_lut[i].clock == dev->cfg.clock)
break;
}
- adc_cw = af9033_div(state, clock_adc_lut[i].adc, 1000000ul, 19ul);
+ adc_cw = af9033_div(dev, clock_adc_lut[i].adc, 1000000ul, 19ul);
buf[0] = (adc_cw >> 0) & 0xff;
buf[1] = (adc_cw >> 8) & 0xff;
buf[2] = (adc_cw >> 16) & 0xff;
- dev_dbg(&state->i2c->dev, "%s: adc=%d adc_cw=%06x\n",
- __func__, clock_adc_lut[i].adc, adc_cw);
+ dev_dbg(&dev->client->dev, "adc=%d adc_cw=%06x\n",
+ clock_adc_lut[i].adc, adc_cw);
- ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
+ ret = af9033_wr_regs(dev, 0x80f1cd, buf, 3);
if (ret < 0)
goto err;
/* program register table */
for (i = 0; i < ARRAY_SIZE(tab); i++) {
- ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val,
+ ret = af9033_wr_reg_mask(dev, tab[i].reg, tab[i].val,
tab[i].mask);
if (ret < 0)
goto err;
}
- /* feed clock to RF tuner */
- switch (state->cfg.tuner) {
- case AF9033_TUNER_IT9135_38:
- case AF9033_TUNER_IT9135_51:
- case AF9033_TUNER_IT9135_52:
- case AF9033_TUNER_IT9135_60:
- case AF9033_TUNER_IT9135_61:
- case AF9033_TUNER_IT9135_62:
- ret = af9033_wr_reg(state, 0x80fba8, 0x00);
+ /* clock output */
+ if (dev->cfg.dyn0_clk) {
+ ret = af9033_wr_reg(dev, 0x80fba8, 0x00);
if (ret < 0)
goto err;
}
/* settings for TS interface */
- if (state->cfg.ts_mode == AF9033_TS_MODE_USB) {
- ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01);
+ if (dev->cfg.ts_mode == AF9033_TS_MODE_USB) {
+ ret = af9033_wr_reg_mask(dev, 0x80f9a5, 0x00, 0x01);
if (ret < 0)
goto err;
- ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x80f9b5, 0x01, 0x01);
if (ret < 0)
goto err;
} else {
- ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x80f990, 0x00, 0x01);
if (ret < 0)
goto err;
- ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x80f9b5, 0x00, 0x01);
if (ret < 0)
goto err;
}
/* load OFSM settings */
- dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__);
- switch (state->cfg.tuner) {
+ dev_dbg(&dev->client->dev, "load ofsm settings\n");
+ switch (dev->cfg.tuner) {
case AF9033_TUNER_IT9135_38:
case AF9033_TUNER_IT9135_51:
case AF9033_TUNER_IT9135_52:
@@ -367,14 +359,13 @@ static int af9033_init(struct dvb_frontend *fe)
break;
}
- ret = af9033_wr_reg_val_tab(state, init, len);
+ ret = af9033_wr_reg_val_tab(dev, init, len);
if (ret < 0)
goto err;
/* load tuner specific settings */
- dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
- __func__);
- switch (state->cfg.tuner) {
+ dev_dbg(&dev->client->dev, "load tuner specific settings\n");
+ switch (dev->cfg.tuner) {
case AF9033_TUNER_TUA9001:
len = ARRAY_SIZE(tuner_init_tua9001);
init = tuner_init_tua9001;
@@ -424,90 +415,108 @@ static int af9033_init(struct dvb_frontend *fe)
init = tuner_init_it9135_62;
break;
default:
- dev_dbg(&state->i2c->dev, "%s: unsupported tuner ID=%d\n",
- __func__, state->cfg.tuner);
+ dev_dbg(&dev->client->dev, "unsupported tuner ID=%d\n",
+ dev->cfg.tuner);
ret = -ENODEV;
goto err;
}
- ret = af9033_wr_reg_val_tab(state, init, len);
+ ret = af9033_wr_reg_val_tab(dev, init, len);
if (ret < 0)
goto err;
- if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
- ret = af9033_wr_reg_mask(state, 0x00d91c, 0x01, 0x01);
+ if (dev->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
+ ret = af9033_wr_reg_mask(dev, 0x00d91c, 0x01, 0x01);
if (ret < 0)
goto err;
- ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x00d917, 0x00, 0x01);
if (ret < 0)
goto err;
- ret = af9033_wr_reg_mask(state, 0x00d916, 0x00, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x00d916, 0x00, 0x01);
if (ret < 0)
goto err;
}
- switch (state->cfg.tuner) {
+ switch (dev->cfg.tuner) {
case AF9033_TUNER_IT9135_60:
case AF9033_TUNER_IT9135_61:
case AF9033_TUNER_IT9135_62:
- ret = af9033_wr_reg(state, 0x800000, 0x01);
+ ret = af9033_wr_reg(dev, 0x800000, 0x01);
if (ret < 0)
goto err;
}
- state->bandwidth_hz = 0; /* force to program all parameters */
+ dev->bandwidth_hz = 0; /* force to program all parameters */
+ /* init stats here in order signal app which stats are supported */
+ c->strength.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_count.len = 1;
+ c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_error.len = 1;
+ c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.len = 1;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.len = 1;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ /* start statistics polling */
+ schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_sleep(struct dvb_frontend *fe)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
int ret, i;
u8 tmp;
- ret = af9033_wr_reg(state, 0x80004c, 1);
+ /* stop statistics polling */
+ cancel_delayed_work_sync(&dev->stat_work);
+
+ ret = af9033_wr_reg(dev, 0x80004c, 1);
if (ret < 0)
goto err;
- ret = af9033_wr_reg(state, 0x800000, 0);
+ ret = af9033_wr_reg(dev, 0x800000, 0);
if (ret < 0)
goto err;
for (i = 100, tmp = 1; i && tmp; i--) {
- ret = af9033_rd_reg(state, 0x80004c, &tmp);
+ ret = af9033_rd_reg(dev, 0x80004c, &tmp);
if (ret < 0)
goto err;
usleep_range(200, 10000);
}
- dev_dbg(&state->i2c->dev, "%s: loop=%d\n", __func__, i);
+ dev_dbg(&dev->client->dev, "loop=%d\n", i);
if (i == 0) {
ret = -ETIMEDOUT;
goto err;
}
- ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08);
+ ret = af9033_wr_reg_mask(dev, 0x80fb24, 0x08, 0x08);
if (ret < 0)
goto err;
/* prevent current leak (?) */
- if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
+ if (dev->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
/* enable parallel TS */
- ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x00d917, 0x00, 0x01);
if (ret < 0)
goto err;
- ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x00d916, 0x01, 0x01);
if (ret < 0)
goto err;
}
@@ -515,7 +524,7 @@ static int af9033_sleep(struct dvb_frontend *fe)
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
@@ -533,14 +542,14 @@ static int af9033_get_tune_settings(struct dvb_frontend *fe,
static int af9033_set_frontend(struct dvb_frontend *fe)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i, spec_inv, sampling_freq;
u8 tmp, buf[3], bandwidth_reg_val;
u32 if_frequency, freq_cw, adc_freq;
- dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
- __func__, c->frequency, c->bandwidth_hz);
+ dev_dbg(&dev->client->dev, "frequency=%d bandwidth_hz=%d\n",
+ c->frequency, c->bandwidth_hz);
/* check bandwidth */
switch (c->bandwidth_hz) {
@@ -554,8 +563,7 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
bandwidth_reg_val = 0x02;
break;
default:
- dev_dbg(&state->i2c->dev, "%s: invalid bandwidth_hz\n",
- __func__);
+ dev_dbg(&dev->client->dev, "invalid bandwidth_hz\n");
ret = -EINVAL;
goto err;
}
@@ -565,23 +573,23 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
fe->ops.tuner_ops.set_params(fe);
/* program CFOE coefficients */
- if (c->bandwidth_hz != state->bandwidth_hz) {
+ if (c->bandwidth_hz != dev->bandwidth_hz) {
for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
- if (coeff_lut[i].clock == state->cfg.clock &&
+ if (coeff_lut[i].clock == dev->cfg.clock &&
coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
break;
}
}
- ret = af9033_wr_regs(state, 0x800001,
+ ret = af9033_wr_regs(dev, 0x800001,
coeff_lut[i].val, sizeof(coeff_lut[i].val));
}
/* program frequency control */
- if (c->bandwidth_hz != state->bandwidth_hz) {
- spec_inv = state->cfg.spec_inv ? -1 : 1;
+ if (c->bandwidth_hz != dev->bandwidth_hz) {
+ spec_inv = dev->cfg.spec_inv ? -1 : 1;
for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
- if (clock_adc_lut[i].clock == state->cfg.clock)
+ if (clock_adc_lut[i].clock == dev->cfg.clock)
break;
}
adc_freq = clock_adc_lut[i].adc;
@@ -602,12 +610,12 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
else
sampling_freq *= -1;
- freq_cw = af9033_div(state, sampling_freq, adc_freq, 23ul);
+ freq_cw = af9033_div(dev, sampling_freq, adc_freq, 23ul);
if (spec_inv == -1)
freq_cw = 0x800000 - freq_cw;
- if (state->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
+ if (dev->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
freq_cw /= 2;
buf[0] = (freq_cw >> 0) & 0xff;
@@ -618,26 +626,26 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
if (if_frequency == 0)
buf[2] = 0;
- ret = af9033_wr_regs(state, 0x800029, buf, 3);
+ ret = af9033_wr_regs(dev, 0x800029, buf, 3);
if (ret < 0)
goto err;
- state->bandwidth_hz = c->bandwidth_hz;
+ dev->bandwidth_hz = c->bandwidth_hz;
}
- ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03);
+ ret = af9033_wr_reg_mask(dev, 0x80f904, bandwidth_reg_val, 0x03);
if (ret < 0)
goto err;
- ret = af9033_wr_reg(state, 0x800040, 0x00);
+ ret = af9033_wr_reg(dev, 0x800040, 0x00);
if (ret < 0)
goto err;
- ret = af9033_wr_reg(state, 0x800047, 0x00);
+ ret = af9033_wr_reg(dev, 0x800047, 0x00);
if (ret < 0)
goto err;
- ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x80f999, 0x00, 0x01);
if (ret < 0)
goto err;
@@ -646,33 +654,33 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
else
tmp = 0x01; /* UHF */
- ret = af9033_wr_reg(state, 0x80004b, tmp);
+ ret = af9033_wr_reg(dev, 0x80004b, tmp);
if (ret < 0)
goto err;
- ret = af9033_wr_reg(state, 0x800000, 0x00);
+ ret = af9033_wr_reg(dev, 0x800000, 0x00);
if (ret < 0)
goto err;
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_get_frontend(struct dvb_frontend *fe)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
u8 buf[8];
- dev_dbg(&state->i2c->dev, "%s:\n", __func__);
+ dev_dbg(&dev->client->dev, "\n");
/* read all needed registers */
- ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
+ ret = af9033_rd_regs(dev, 0x80f900, buf, sizeof(buf));
if (ret < 0)
goto err;
@@ -784,21 +792,21 @@ static int af9033_get_frontend(struct dvb_frontend *fe)
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
int ret;
u8 tmp;
*status = 0;
/* radio channel status, 0=no result, 1=has signal, 2=no signal */
- ret = af9033_rd_reg(state, 0x800047, &tmp);
+ ret = af9033_rd_reg(dev, 0x800047, &tmp);
if (ret < 0)
goto err;
@@ -808,7 +816,7 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
if (tmp != 0x02) {
/* TPS lock */
- ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01);
+ ret = af9033_rd_reg_mask(dev, 0x80f5a9, &tmp, 0x01);
if (ret < 0)
goto err;
@@ -817,7 +825,7 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
FE_HAS_VITERBI;
/* full lock */
- ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01);
+ ret = af9033_rd_reg_mask(dev, 0x80f999, &tmp, 0x01);
if (ret < 0)
goto err;
@@ -827,76 +835,38 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
FE_HAS_LOCK;
}
+ dev->fe_status = *status;
+
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct af9033_state *state = fe->demodulator_priv;
- int ret, i, len;
- u8 buf[3], tmp;
- u32 snr_val;
- const struct val_snr *uninitialized_var(snr_lut);
-
- /* read value */
- ret = af9033_rd_regs(state, 0x80002c, buf, 3);
- if (ret < 0)
- goto err;
+ struct af9033_dev *dev = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
- snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-
- /* read current modulation */
- ret = af9033_rd_reg(state, 0x80f903, &tmp);
- if (ret < 0)
- goto err;
-
- switch ((tmp >> 0) & 3) {
- case 0:
- len = ARRAY_SIZE(qpsk_snr_lut);
- snr_lut = qpsk_snr_lut;
- break;
- case 1:
- len = ARRAY_SIZE(qam16_snr_lut);
- snr_lut = qam16_snr_lut;
- break;
- case 2:
- len = ARRAY_SIZE(qam64_snr_lut);
- snr_lut = qam64_snr_lut;
- break;
- default:
- goto err;
- }
-
- for (i = 0; i < len; i++) {
- tmp = snr_lut[i].snr;
-
- if (snr_val < snr_lut[i].val)
- break;
- }
-
- *snr = tmp * 10; /* dB/10 */
+ /* use DVBv5 CNR */
+ if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
+ *snr = div_s64(c->cnr.stat[0].svalue, 100); /* 1000x => 10x */
+ else
+ *snr = 0;
return 0;
-
-err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
-
- return ret;
}
static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
int ret;
u8 strength2;
/* read signal strength of 0-100 scale */
- ret = af9033_rd_reg(state, 0x800048, &strength2);
+ ret = af9033_rd_reg(dev, 0x800048, &strength2);
if (ret < 0)
goto err;
@@ -906,244 +876,225 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
-
- return ret;
-}
-
-static int af9033_update_ch_stat(struct af9033_state *state)
-{
- int ret = 0;
- u32 err_cnt, bit_cnt;
- u16 abort_cnt;
- u8 buf[7];
-
- /* only update data every half second */
- if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) {
- ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf));
- if (ret < 0)
- goto err;
- /* in 8 byte packets? */
- abort_cnt = (buf[1] << 8) + buf[0];
- /* in bits */
- err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2];
- /* in 8 byte packets? always(?) 0x2710 = 10000 */
- bit_cnt = (buf[6] << 8) + buf[5];
-
- if (bit_cnt < abort_cnt) {
- abort_cnt = 1000;
- state->ber = 0xffffffff;
- } else {
- /* 8 byte packets, that have not been rejected already */
- bit_cnt -= (u32)abort_cnt;
- if (bit_cnt == 0) {
- state->ber = 0xffffffff;
- } else {
- err_cnt -= (u32)abort_cnt * 8 * 8;
- bit_cnt *= 8 * 8;
- state->ber = err_cnt * (0xffffffff / bit_cnt);
- }
- }
- state->ucb += abort_cnt;
- state->last_stat_check = jiffies;
- }
-
- return 0;
-err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber)
{
- struct af9033_state *state = fe->demodulator_priv;
- int ret;
-
- ret = af9033_update_ch_stat(state);
- if (ret < 0)
- return ret;
+ struct af9033_dev *dev = fe->demodulator_priv;
- *ber = state->ber;
+ *ber = (dev->post_bit_error - dev->post_bit_error_prev);
+ dev->post_bit_error_prev = dev->post_bit_error;
return 0;
}
static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
- struct af9033_state *state = fe->demodulator_priv;
- int ret;
-
- ret = af9033_update_ch_stat(state);
- if (ret < 0)
- return ret;
-
- *ucblocks = state->ucb;
+ struct af9033_dev *dev = fe->demodulator_priv;
+ *ucblocks = dev->error_block_count;
return 0;
}
static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
int ret;
- dev_dbg(&state->i2c->dev, "%s: enable=%d\n", __func__, enable);
+ dev_dbg(&dev->client->dev, "enable=%d\n", enable);
- ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x00fa04, enable, 0x01);
if (ret < 0)
goto err;
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
int ret;
- dev_dbg(&state->i2c->dev, "%s: onoff=%d\n", __func__, onoff);
+ dev_dbg(&dev->client->dev, "onoff=%d\n", onoff);
- ret = af9033_wr_reg_mask(state, 0x80f993, onoff, 0x01);
+ ret = af9033_wr_reg_mask(dev, 0x80f993, onoff, 0x01);
if (ret < 0)
goto err;
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
-static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid, int onoff)
+static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
+ int onoff)
{
- struct af9033_state *state = fe->demodulator_priv;
+ struct af9033_dev *dev = fe->demodulator_priv;
int ret;
u8 wbuf[2] = {(pid >> 0) & 0xff, (pid >> 8) & 0xff};
- dev_dbg(&state->i2c->dev, "%s: index=%d pid=%04x onoff=%d\n",
- __func__, index, pid, onoff);
+ dev_dbg(&dev->client->dev, "index=%d pid=%04x onoff=%d\n",
+ index, pid, onoff);
if (pid > 0x1fff)
return 0;
- ret = af9033_wr_regs(state, 0x80f996, wbuf, 2);
+ ret = af9033_wr_regs(dev, 0x80f996, wbuf, 2);
if (ret < 0)
goto err;
- ret = af9033_wr_reg(state, 0x80f994, onoff);
+ ret = af9033_wr_reg(dev, 0x80f994, onoff);
if (ret < 0)
goto err;
- ret = af9033_wr_reg(state, 0x80f995, index);
+ ret = af9033_wr_reg(dev, 0x80f995, index);
if (ret < 0)
goto err;
return 0;
err:
- dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
}
-static struct dvb_frontend_ops af9033_ops;
-
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
- struct i2c_adapter *i2c,
- struct af9033_ops *ops)
+static void af9033_stat_work(struct work_struct *work)
{
- int ret;
- struct af9033_state *state;
- u8 buf[8];
+ struct af9033_dev *dev = container_of(work, struct af9033_dev, stat_work.work);
+ struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
+ int ret, tmp, i, len;
+ u8 u8tmp, buf[7];
+
+ dev_dbg(&dev->client->dev, "\n");
+
+ /* signal strength */
+ if (dev->fe_status & FE_HAS_SIGNAL) {
+ if (dev->is_af9035) {
+ ret = af9033_rd_reg(dev, 0x80004a, &u8tmp);
+ tmp = -u8tmp * 1000;
+ } else {
+ ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp);
+ tmp = (u8tmp - 100) * 1000;
+ }
+ if (ret)
+ goto err;
- dev_dbg(&i2c->dev, "%s:\n", __func__);
+ c->strength.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+ c->strength.stat[0].svalue = tmp;
+ } else {
+ c->strength.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
- /* allocate memory for the internal state */
- state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
- if (state == NULL)
- goto err;
+ /* CNR */
+ if (dev->fe_status & FE_HAS_VITERBI) {
+ u32 snr_val;
+ const struct val_snr *snr_lut;
- /* setup the state */
- state->i2c = i2c;
- memcpy(&state->cfg, config, sizeof(struct af9033_config));
+ /* read value */
+ ret = af9033_rd_regs(dev, 0x80002c, buf, 3);
+ if (ret)
+ goto err;
- if (state->cfg.clock != 12000000) {
- dev_err(&state->i2c->dev, "%s: af9033: unsupported clock=%d, " \
- "only 12000000 Hz is supported currently\n",
- KBUILD_MODNAME, state->cfg.clock);
- goto err;
- }
+ snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
- /* firmware version */
- ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4);
- if (ret < 0)
- goto err;
+ /* read current modulation */
+ ret = af9033_rd_reg(dev, 0x80f903, &u8tmp);
+ if (ret)
+ goto err;
- ret = af9033_rd_regs(state, 0x804191, &buf[4], 4);
- if (ret < 0)
- goto err;
+ switch ((u8tmp >> 0) & 3) {
+ case 0:
+ len = ARRAY_SIZE(qpsk_snr_lut);
+ snr_lut = qpsk_snr_lut;
+ break;
+ case 1:
+ len = ARRAY_SIZE(qam16_snr_lut);
+ snr_lut = qam16_snr_lut;
+ break;
+ case 2:
+ len = ARRAY_SIZE(qam64_snr_lut);
+ snr_lut = qam64_snr_lut;
+ break;
+ default:
+ goto err_schedule_delayed_work;
+ }
- dev_info(&state->i2c->dev, "%s: firmware version: LINK=%d.%d.%d.%d " \
- "OFDM=%d.%d.%d.%d\n", KBUILD_MODNAME, buf[0], buf[1],
- buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+ for (i = 0; i < len; i++) {
+ tmp = snr_lut[i].snr * 1000;
+ if (snr_val < snr_lut[i].val)
+ break;
+ }
- /* sleep */
- switch (state->cfg.tuner) {
- case AF9033_TUNER_IT9135_38:
- case AF9033_TUNER_IT9135_51:
- case AF9033_TUNER_IT9135_52:
- case AF9033_TUNER_IT9135_60:
- case AF9033_TUNER_IT9135_61:
- case AF9033_TUNER_IT9135_62:
- /* IT9135 did not like to sleep at that early */
- break;
- default:
- ret = af9033_wr_reg(state, 0x80004c, 1);
- if (ret < 0)
- goto err;
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+ c->cnr.stat[0].svalue = tmp;
+ } else {
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
- ret = af9033_wr_reg(state, 0x800000, 0);
- if (ret < 0)
+ /* UCB/PER/BER */
+ if (dev->fe_status & FE_HAS_LOCK) {
+ /* outer FEC, 204 byte packets */
+ u16 abort_packet_count, rsd_packet_count;
+ /* inner FEC, bits */
+ u32 rsd_bit_err_count;
+
+ /*
+ * Packet count used for measurement is 10000
+ * (rsd_packet_count). Maybe it should be increased?
+ */
+
+ ret = af9033_rd_regs(dev, 0x800032, buf, 7);
+ if (ret)
goto err;
- }
- /* configure internal TS mode */
- switch (state->cfg.ts_mode) {
- case AF9033_TS_MODE_PARALLEL:
- state->ts_mode_parallel = true;
- break;
- case AF9033_TS_MODE_SERIAL:
- state->ts_mode_serial = true;
- break;
- case AF9033_TS_MODE_USB:
- /* usb mode for AF9035 */
- default:
- break;
- }
+ abort_packet_count = (buf[1] << 8) | (buf[0] << 0);
+ rsd_bit_err_count = (buf[4] << 16) | (buf[3] << 8) | buf[2];
+ rsd_packet_count = (buf[6] << 8) | (buf[5] << 0);
- /* create dvb_frontend */
- memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
- state->fe.demodulator_priv = state;
+ dev->error_block_count += abort_packet_count;
+ dev->total_block_count += rsd_packet_count;
+ dev->post_bit_error += rsd_bit_err_count;
+ dev->post_bit_count += rsd_packet_count * 204 * 8;
- if (ops) {
- ops->pid_filter = af9033_pid_filter;
- ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
- }
+ c->block_count.len = 1;
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].uvalue = dev->total_block_count;
+
+ c->block_error.len = 1;
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[0].uvalue = dev->error_block_count;
+
+ c->post_bit_count.len = 1;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
- return &state->fe;
+ c->post_bit_error.len = 1;
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
+ }
+err_schedule_delayed_work:
+ schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
+ return;
err:
- kfree(state);
- return NULL;
+ dev_dbg(&dev->client->dev, "failed=%d\n", ret);
}
-EXPORT_SYMBOL(af9033_attach);
static struct dvb_frontend_ops af9033_ops = {
.delsys = { SYS_DVBT },
@@ -1170,8 +1121,6 @@ static struct dvb_frontend_ops af9033_ops = {
FE_CAN_MUTE_TS
},
- .release = af9033_release,
-
.init = af9033_init,
.sleep = af9033_sleep,
@@ -1188,6 +1137,150 @@ static struct dvb_frontend_ops af9033_ops = {
.i2c_gate_ctrl = af9033_i2c_gate_ctrl,
};
+static int af9033_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct af9033_config *cfg = client->dev.platform_data;
+ struct af9033_dev *dev;
+ int ret;
+ u8 buf[8];
+ u32 reg;
+
+ /* allocate memory for the internal state */
+ dev = kzalloc(sizeof(struct af9033_dev), GFP_KERNEL);
+ if (dev == NULL) {
+ ret = -ENOMEM;
+ dev_err(&client->dev, "Could not allocate memory for state\n");
+ goto err;
+ }
+
+ /* setup the state */
+ dev->client = client;
+ INIT_DELAYED_WORK(&dev->stat_work, af9033_stat_work);
+ memcpy(&dev->cfg, cfg, sizeof(struct af9033_config));
+
+ if (dev->cfg.clock != 12000000) {
+ ret = -ENODEV;
+ dev_err(&dev->client->dev,
+ "unsupported clock %d Hz, only 12000000 Hz is supported currently\n",
+ dev->cfg.clock);
+ goto err_kfree;
+ }
+
+ /* firmware version */
+ switch (dev->cfg.tuner) {
+ case AF9033_TUNER_IT9135_38:
+ case AF9033_TUNER_IT9135_51:
+ case AF9033_TUNER_IT9135_52:
+ case AF9033_TUNER_IT9135_60:
+ case AF9033_TUNER_IT9135_61:
+ case AF9033_TUNER_IT9135_62:
+ dev->is_it9135 = true;
+ reg = 0x004bfc;
+ break;
+ default:
+ dev->is_af9035 = true;
+ reg = 0x0083e9;
+ break;
+ }
+
+ ret = af9033_rd_regs(dev, reg, &buf[0], 4);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = af9033_rd_regs(dev, 0x804191, &buf[4], 4);
+ if (ret < 0)
+ goto err_kfree;
+
+ dev_info(&dev->client->dev,
+ "firmware version: LINK %d.%d.%d.%d - OFDM %d.%d.%d.%d\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7]);
+
+ /* sleep */
+ switch (dev->cfg.tuner) {
+ case AF9033_TUNER_IT9135_38:
+ case AF9033_TUNER_IT9135_51:
+ case AF9033_TUNER_IT9135_52:
+ case AF9033_TUNER_IT9135_60:
+ case AF9033_TUNER_IT9135_61:
+ case AF9033_TUNER_IT9135_62:
+ /* IT9135 did not like to sleep at that early */
+ break;
+ default:
+ ret = af9033_wr_reg(dev, 0x80004c, 1);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = af9033_wr_reg(dev, 0x800000, 0);
+ if (ret < 0)
+ goto err_kfree;
+ }
+
+ /* configure internal TS mode */
+ switch (dev->cfg.ts_mode) {
+ case AF9033_TS_MODE_PARALLEL:
+ dev->ts_mode_parallel = true;
+ break;
+ case AF9033_TS_MODE_SERIAL:
+ dev->ts_mode_serial = true;
+ break;
+ case AF9033_TS_MODE_USB:
+ /* usb mode for AF9035 */
+ default:
+ break;
+ }
+
+ /* create dvb_frontend */
+ memcpy(&dev->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
+ dev->fe.demodulator_priv = dev;
+ *cfg->fe = &dev->fe;
+ if (cfg->ops) {
+ cfg->ops->pid_filter = af9033_pid_filter;
+ cfg->ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
+ }
+ i2c_set_clientdata(client, dev);
+
+ dev_info(&dev->client->dev, "Afatech AF9033 successfully attached\n");
+ return 0;
+err_kfree:
+ kfree(dev);
+err:
+ dev_dbg(&client->dev, "failed=%d\n", ret);
+ return ret;
+}
+
+static int af9033_remove(struct i2c_client *client)
+{
+ struct af9033_dev *dev = i2c_get_clientdata(client);
+
+ dev_dbg(&dev->client->dev, "\n");
+
+ dev->fe.ops.release = NULL;
+ dev->fe.demodulator_priv = NULL;
+ kfree(dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id af9033_id_table[] = {
+ {"af9033", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, af9033_id_table);
+
+static struct i2c_driver af9033_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "af9033",
+ },
+ .probe = af9033_probe,
+ .remove = af9033_remove,
+ .id_table = af9033_id_table,
+};
+
+module_i2c_driver(af9033_driver);
+
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/af9033.h b/drivers/media/dvb-frontends/af9033.h
index 539f4db..6ad22b6 100644
--- a/drivers/media/dvb-frontends/af9033.h
+++ b/drivers/media/dvb-frontends/af9033.h
@@ -24,13 +24,12 @@
#include <linux/kconfig.h>
+/*
+ * I2C address (TODO: are these in 8-bit format?)
+ * 0x38, 0x3a, 0x3c, 0x3e
+ */
struct af9033_config {
/*
- * I2C address
- */
- u8 i2c_addr;
-
- /*
* clock Hz
* 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000,
* 30000000, 36000000, 20480000, 16384000
@@ -75,8 +74,23 @@ struct af9033_config {
* input spectrum inversion
*/
bool spec_inv;
-};
+ /*
+ *
+ */
+ bool dyn0_clk;
+
+ /*
+ * PID filter ops
+ */
+ struct af9033_ops *ops;
+
+ /*
+ * frontend
+ * returned by that driver
+ */
+ struct dvb_frontend **fe;
+};
struct af9033_ops {
int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
@@ -84,36 +98,4 @@ struct af9033_ops {
int onoff);
};
-
-#if IS_ENABLED(CONFIG_DVB_AF9033)
-extern
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
- struct i2c_adapter *i2c,
- struct af9033_ops *ops);
-
-#else
-static inline
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
- struct i2c_adapter *i2c,
- struct af9033_ops *ops)
-{
- pr_warn("%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-
-static inline int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
-{
- pr_warn("%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
- int onoff)
-{
- pr_warn("%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-#endif
-
#endif /* AF9033_H */
diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h
index ded7b67..c12c92c 100644
--- a/drivers/media/dvb-frontends/af9033_priv.h
+++ b/drivers/media/dvb-frontends/af9033_priv.h
@@ -24,6 +24,7 @@
#include "dvb_frontend.h"
#include "af9033.h"
+#include <linux/math64.h>
struct reg_val {
u32 reg;
diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c
new file mode 100644
index 0000000..4936658
--- /dev/null
+++ b/drivers/media/dvb-frontends/as102_fe.c
@@ -0,0 +1,480 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <dvb_frontend.h>
+
+#include "as102_fe.h"
+
+struct as102_state {
+ struct dvb_frontend frontend;
+ struct as10x_demod_stats demod_stats;
+
+ const struct as102_fe_ops *ops;
+ void *priv;
+ uint8_t elna_cfg;
+
+ /* signal strength */
+ uint16_t signal_strength;
+ /* bit error rate */
+ uint32_t ber;
+};
+
+static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
+{
+ uint8_t c;
+
+ switch (arg) {
+ case FEC_1_2:
+ c = CODE_RATE_1_2;
+ break;
+ case FEC_2_3:
+ c = CODE_RATE_2_3;
+ break;
+ case FEC_3_4:
+ c = CODE_RATE_3_4;
+ break;
+ case FEC_5_6:
+ c = CODE_RATE_5_6;
+ break;
+ case FEC_7_8:
+ c = CODE_RATE_7_8;
+ break;
+ default:
+ c = CODE_RATE_UNKNOWN;
+ break;
+ }
+
+ return c;
+}
+
+static int as102_fe_set_frontend(struct dvb_frontend *fe)
+{
+ struct as102_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct as10x_tune_args tune_args = { 0 };
+
+ /* set frequency */
+ tune_args.freq = c->frequency / 1000;
+
+ /* fix interleaving_mode */
+ tune_args.interleaving_mode = INTLV_NATIVE;
+
+ switch (c->bandwidth_hz) {
+ case 8000000:
+ tune_args.bandwidth = BW_8_MHZ;
+ break;
+ case 7000000:
+ tune_args.bandwidth = BW_7_MHZ;
+ break;
+ case 6000000:
+ tune_args.bandwidth = BW_6_MHZ;
+ break;
+ default:
+ tune_args.bandwidth = BW_8_MHZ;
+ }
+
+ switch (c->guard_interval) {
+ case GUARD_INTERVAL_1_32:
+ tune_args.guard_interval = GUARD_INT_1_32;
+ break;
+ case GUARD_INTERVAL_1_16:
+ tune_args.guard_interval = GUARD_INT_1_16;
+ break;
+ case GUARD_INTERVAL_1_8:
+ tune_args.guard_interval = GUARD_INT_1_8;
+ break;
+ case GUARD_INTERVAL_1_4:
+ tune_args.guard_interval = GUARD_INT_1_4;
+ break;
+ case GUARD_INTERVAL_AUTO:
+ default:
+ tune_args.guard_interval = GUARD_UNKNOWN;
+ break;
+ }
+
+ switch (c->modulation) {
+ case QPSK:
+ tune_args.modulation = CONST_QPSK;
+ break;
+ case QAM_16:
+ tune_args.modulation = CONST_QAM16;
+ break;
+ case QAM_64:
+ tune_args.modulation = CONST_QAM64;
+ break;
+ default:
+ tune_args.modulation = CONST_UNKNOWN;
+ break;
+ }
+
+ switch (c->transmission_mode) {
+ case TRANSMISSION_MODE_2K:
+ tune_args.transmission_mode = TRANS_MODE_2K;
+ break;
+ case TRANSMISSION_MODE_8K:
+ tune_args.transmission_mode = TRANS_MODE_8K;
+ break;
+ default:
+ tune_args.transmission_mode = TRANS_MODE_UNKNOWN;
+ }
+
+ switch (c->hierarchy) {
+ case HIERARCHY_NONE:
+ tune_args.hierarchy = HIER_NONE;
+ break;
+ case HIERARCHY_1:
+ tune_args.hierarchy = HIER_ALPHA_1;
+ break;
+ case HIERARCHY_2:
+ tune_args.hierarchy = HIER_ALPHA_2;
+ break;
+ case HIERARCHY_4:
+ tune_args.hierarchy = HIER_ALPHA_4;
+ break;
+ case HIERARCHY_AUTO:
+ tune_args.hierarchy = HIER_UNKNOWN;
+ break;
+ }
+
+ pr_debug("as102: tuner parameters: freq: %d bw: 0x%02x gi: 0x%02x\n",
+ c->frequency,
+ tune_args.bandwidth,
+ tune_args.guard_interval);
+
+ /*
+ * Detect a hierarchy selection
+ * if HP/LP are both set to FEC_NONE, HP will be selected.
+ */
+ if ((tune_args.hierarchy != HIER_NONE) &&
+ ((c->code_rate_LP == FEC_NONE) ||
+ (c->code_rate_HP == FEC_NONE))) {
+
+ if (c->code_rate_LP == FEC_NONE) {
+ tune_args.hier_select = HIER_HIGH_PRIORITY;
+ tune_args.code_rate =
+ as102_fe_get_code_rate(c->code_rate_HP);
+ }
+
+ if (c->code_rate_HP == FEC_NONE) {
+ tune_args.hier_select = HIER_LOW_PRIORITY;
+ tune_args.code_rate =
+ as102_fe_get_code_rate(c->code_rate_LP);
+ }
+
+ pr_debug("as102: \thierarchy: 0x%02x selected: %s code_rate_%s: 0x%02x\n",
+ tune_args.hierarchy,
+ tune_args.hier_select == HIER_HIGH_PRIORITY ?
+ "HP" : "LP",
+ tune_args.hier_select == HIER_HIGH_PRIORITY ?
+ "HP" : "LP",
+ tune_args.code_rate);
+ } else {
+ tune_args.code_rate =
+ as102_fe_get_code_rate(c->code_rate_HP);
+ }
+
+ /* Set frontend arguments */
+ return state->ops->set_tune(state->priv, &tune_args);
+}
+
+static int as102_fe_get_frontend(struct dvb_frontend *fe)
+{
+ struct as102_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret = 0;
+ struct as10x_tps tps = { 0 };
+
+ /* send abilis command: GET_TPS */
+ ret = state->ops->get_tps(state->priv, &tps);
+ if (ret < 0)
+ return ret;
+
+ /* extract constellation */
+ switch (tps.modulation) {
+ case CONST_QPSK:
+ c->modulation = QPSK;
+ break;
+ case CONST_QAM16:
+ c->modulation = QAM_16;
+ break;
+ case CONST_QAM64:
+ c->modulation = QAM_64;
+ break;
+ }
+
+ /* extract hierarchy */
+ switch (tps.hierarchy) {
+ case HIER_NONE:
+ c->hierarchy = HIERARCHY_NONE;
+ break;
+ case HIER_ALPHA_1:
+ c->hierarchy = HIERARCHY_1;
+ break;
+ case HIER_ALPHA_2:
+ c->hierarchy = HIERARCHY_2;
+ break;
+ case HIER_ALPHA_4:
+ c->hierarchy = HIERARCHY_4;
+ break;
+ }
+
+ /* extract code rate HP */
+ switch (tps.code_rate_HP) {
+ case CODE_RATE_1_2:
+ c->code_rate_HP = FEC_1_2;
+ break;
+ case CODE_RATE_2_3:
+ c->code_rate_HP = FEC_2_3;
+ break;
+ case CODE_RATE_3_4:
+ c->code_rate_HP = FEC_3_4;
+ break;
+ case CODE_RATE_5_6:
+ c->code_rate_HP = FEC_5_6;
+ break;
+ case CODE_RATE_7_8:
+ c->code_rate_HP = FEC_7_8;
+ break;
+ }
+
+ /* extract code rate LP */
+ switch (tps.code_rate_LP) {
+ case CODE_RATE_1_2:
+ c->code_rate_LP = FEC_1_2;
+ break;
+ case CODE_RATE_2_3:
+ c->code_rate_LP = FEC_2_3;
+ break;
+ case CODE_RATE_3_4:
+ c->code_rate_LP = FEC_3_4;
+ break;
+ case CODE_RATE_5_6:
+ c->code_rate_LP = FEC_5_6;
+ break;
+ case CODE_RATE_7_8:
+ c->code_rate_LP = FEC_7_8;
+ break;
+ }
+
+ /* extract guard interval */
+ switch (tps.guard_interval) {
+ case GUARD_INT_1_32:
+ c->guard_interval = GUARD_INTERVAL_1_32;
+ break;
+ case GUARD_INT_1_16:
+ c->guard_interval = GUARD_INTERVAL_1_16;
+ break;
+ case GUARD_INT_1_8:
+ c->guard_interval = GUARD_INTERVAL_1_8;
+ break;
+ case GUARD_INT_1_4:
+ c->guard_interval = GUARD_INTERVAL_1_4;
+ break;
+ }
+
+ /* extract transmission mode */
+ switch (tps.transmission_mode) {
+ case TRANS_MODE_2K:
+ c->transmission_mode = TRANSMISSION_MODE_2K;
+ break;
+ case TRANS_MODE_8K:
+ c->transmission_mode = TRANSMISSION_MODE_8K;
+ break;
+ }
+
+ return 0;
+}
+
+static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *settings) {
+
+ settings->min_delay_ms = 1000;
+
+ return 0;
+}
+
+static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ int ret = 0;
+ struct as102_state *state = fe->demodulator_priv;
+ struct as10x_tune_status tstate = { 0 };
+
+ /* send abilis command: GET_TUNE_STATUS */
+ ret = state->ops->get_status(state->priv, &tstate);
+ if (ret < 0)
+ return ret;
+
+ state->signal_strength = tstate.signal_strength;
+ state->ber = tstate.BER;
+
+ switch (tstate.tune_state) {
+ case TUNE_STATUS_SIGNAL_DVB_OK:
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ break;
+ case TUNE_STATUS_STREAM_DETECTED:
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
+ FE_HAS_VITERBI;
+ break;
+ case TUNE_STATUS_STREAM_TUNED:
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
+ FE_HAS_LOCK | FE_HAS_VITERBI;
+ break;
+ default:
+ *status = TUNE_STATUS_NOT_TUNED;
+ }
+
+ pr_debug("as102: tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
+ tstate.tune_state, tstate.signal_strength,
+ tstate.PER, tstate.BER);
+
+ if (!(*status & FE_HAS_LOCK)) {
+ memset(&state->demod_stats, 0, sizeof(state->demod_stats));
+ return 0;
+ }
+
+ ret = state->ops->get_stats(state->priv, &state->demod_stats);
+ if (ret < 0)
+ memset(&state->demod_stats, 0, sizeof(state->demod_stats));
+
+ return ret;
+}
+
+/*
+ * Note:
+ * - in AS102 SNR=MER
+ * - the SNR will be returned in linear terms, i.e. not in dB
+ * - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
+ * - the accuracy is >2dB for SNR values outside this range
+ */
+static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct as102_state *state = fe->demodulator_priv;
+
+ *snr = state->demod_stats.mer;
+
+ return 0;
+}
+
+static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct as102_state *state = fe->demodulator_priv;
+
+ *ber = state->ber;
+
+ return 0;
+}
+
+static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
+ u16 *strength)
+{
+ struct as102_state *state = fe->demodulator_priv;
+
+ *strength = (((0xffff * 400) * state->signal_strength + 41000) * 2);
+
+ return 0;
+}
+
+static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct as102_state *state = fe->demodulator_priv;
+
+ if (state->demod_stats.has_started)
+ *ucblocks = state->demod_stats.bad_frame_count;
+ else
+ *ucblocks = 0;
+
+ return 0;
+}
+
+static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+ struct as102_state *state = fe->demodulator_priv;
+
+ return state->ops->stream_ctrl(state->priv, acquire,
+ state->elna_cfg);
+}
+
+static void as102_fe_release(struct dvb_frontend *fe)
+{
+ struct as102_state *state = fe->demodulator_priv;
+
+ kfree(state);
+}
+
+
+static struct dvb_frontend_ops as102_fe_ops = {
+ .delsys = { SYS_DVBT },
+ .info = {
+ .name = "Abilis AS102 DVB-T",
+ .frequency_min = 174000000,
+ .frequency_max = 862000000,
+ .frequency_stepsize = 166667,
+ .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_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
+ | FE_CAN_QAM_AUTO
+ | FE_CAN_TRANSMISSION_MODE_AUTO
+ | FE_CAN_GUARD_INTERVAL_AUTO
+ | FE_CAN_HIERARCHY_AUTO
+ | FE_CAN_RECOVER
+ | FE_CAN_MUTE_TS
+ },
+
+ .set_frontend = as102_fe_set_frontend,
+ .get_frontend = as102_fe_get_frontend,
+ .get_tune_settings = as102_fe_get_tune_settings,
+
+ .read_status = as102_fe_read_status,
+ .read_snr = as102_fe_read_snr,
+ .read_ber = as102_fe_read_ber,
+ .read_signal_strength = as102_fe_read_signal_strength,
+ .read_ucblocks = as102_fe_read_ucblocks,
+ .ts_bus_ctrl = as102_fe_ts_bus_ctrl,
+ .release = as102_fe_release,
+};
+
+struct dvb_frontend *as102_attach(const char *name,
+ const struct as102_fe_ops *ops,
+ void *priv,
+ uint8_t elna_cfg)
+{
+ struct as102_state *state;
+ struct dvb_frontend *fe;
+
+ state = kzalloc(sizeof(struct as102_state), GFP_KERNEL);
+ if (state == NULL) {
+ pr_err("%s: unable to allocate memory for state\n", __func__);
+ return NULL;
+ }
+ fe = &state->frontend;
+ fe->demodulator_priv = state;
+ state->ops = ops;
+ state->priv = priv;
+ state->elna_cfg = elna_cfg;
+
+ /* init frontend callback ops */
+ memcpy(&fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
+ strncpy(fe->ops.info.name, name, sizeof(fe->ops.info.name));
+
+ return fe;
+
+}
+EXPORT_SYMBOL_GPL(as102_attach);
+
+MODULE_DESCRIPTION("as102-fe");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");
diff --git a/drivers/media/dvb-frontends/as102_fe.h b/drivers/media/dvb-frontends/as102_fe.h
new file mode 100644
index 0000000..a7c9143
--- /dev/null
+++ b/drivers/media/dvb-frontends/as102_fe.h
@@ -0,0 +1,29 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2014 Mauro Carvalho Chehab <m.chehab@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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 "as102_fe_types.h"
+
+struct as102_fe_ops {
+ int (*set_tune)(void *priv, struct as10x_tune_args *tune_args);
+ int (*get_tps)(void *priv, struct as10x_tps *tps);
+ int (*get_status)(void *priv, struct as10x_tune_status *tstate);
+ int (*get_stats)(void *priv, struct as10x_demod_stats *demod_stats);
+ int (*stream_ctrl)(void *priv, int acquire, uint32_t elna_cfg);
+};
+
+struct dvb_frontend *as102_attach(const char *name,
+ const struct as102_fe_ops *ops,
+ void *priv,
+ uint8_t elna_cfg);
diff --git a/drivers/media/dvb-frontends/as102_fe_types.h b/drivers/media/dvb-frontends/as102_fe_types.h
new file mode 100644
index 0000000..80a5398
--- /dev/null
+++ b/drivers/media/dvb-frontends/as102_fe_types.h
@@ -0,0 +1,188 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _AS10X_TYPES_H_
+#define _AS10X_TYPES_H_
+
+/*********************************/
+/* MACRO DEFINITIONS */
+/*********************************/
+
+/* bandwidth constant values */
+#define BW_5_MHZ 0x00
+#define BW_6_MHZ 0x01
+#define BW_7_MHZ 0x02
+#define BW_8_MHZ 0x03
+
+/* hierarchy priority selection values */
+#define HIER_NO_PRIORITY 0x00
+#define HIER_LOW_PRIORITY 0x01
+#define HIER_HIGH_PRIORITY 0x02
+
+/* constellation available values */
+#define CONST_QPSK 0x00
+#define CONST_QAM16 0x01
+#define CONST_QAM64 0x02
+#define CONST_UNKNOWN 0xFF
+
+/* hierarchy available values */
+#define HIER_NONE 0x00
+#define HIER_ALPHA_1 0x01
+#define HIER_ALPHA_2 0x02
+#define HIER_ALPHA_4 0x03
+#define HIER_UNKNOWN 0xFF
+
+/* interleaving available values */
+#define INTLV_NATIVE 0x00
+#define INTLV_IN_DEPTH 0x01
+#define INTLV_UNKNOWN 0xFF
+
+/* code rate available values */
+#define CODE_RATE_1_2 0x00
+#define CODE_RATE_2_3 0x01
+#define CODE_RATE_3_4 0x02
+#define CODE_RATE_5_6 0x03
+#define CODE_RATE_7_8 0x04
+#define CODE_RATE_UNKNOWN 0xFF
+
+/* guard interval available values */
+#define GUARD_INT_1_32 0x00
+#define GUARD_INT_1_16 0x01
+#define GUARD_INT_1_8 0x02
+#define GUARD_INT_1_4 0x03
+#define GUARD_UNKNOWN 0xFF
+
+/* transmission mode available values */
+#define TRANS_MODE_2K 0x00
+#define TRANS_MODE_8K 0x01
+#define TRANS_MODE_4K 0x02
+#define TRANS_MODE_UNKNOWN 0xFF
+
+/* DVBH signalling available values */
+#define TIMESLICING_PRESENT 0x01
+#define MPE_FEC_PRESENT 0x02
+
+/* tune state available */
+#define TUNE_STATUS_NOT_TUNED 0x00
+#define TUNE_STATUS_IDLE 0x01
+#define TUNE_STATUS_LOCKING 0x02
+#define TUNE_STATUS_SIGNAL_DVB_OK 0x03
+#define TUNE_STATUS_STREAM_DETECTED 0x04
+#define TUNE_STATUS_STREAM_TUNED 0x05
+#define TUNE_STATUS_ERROR 0xFF
+
+/* available TS FID filter types */
+#define TS_PID_TYPE_TS 0
+#define TS_PID_TYPE_PSI_SI 1
+#define TS_PID_TYPE_MPE 2
+
+/* number of echos available */
+#define MAX_ECHOS 15
+
+/* Context types */
+#define CONTEXT_LNA 1010
+#define CONTEXT_ELNA_HYSTERESIS 4003
+#define CONTEXT_ELNA_GAIN 4004
+#define CONTEXT_MER_THRESHOLD 5005
+#define CONTEXT_MER_OFFSET 5006
+#define CONTEXT_IR_STATE 7000
+#define CONTEXT_TSOUT_MSB_FIRST 7004
+#define CONTEXT_TSOUT_FALLING_EDGE 7005
+
+/* Configuration modes */
+#define CFG_MODE_ON 0
+#define CFG_MODE_OFF 1
+#define CFG_MODE_AUTO 2
+
+struct as10x_tps {
+ uint8_t modulation;
+ uint8_t hierarchy;
+ uint8_t interleaving_mode;
+ uint8_t code_rate_HP;
+ uint8_t code_rate_LP;
+ uint8_t guard_interval;
+ uint8_t transmission_mode;
+ uint8_t DVBH_mask_HP;
+ uint8_t DVBH_mask_LP;
+ uint16_t cell_ID;
+} __packed;
+
+struct as10x_tune_args {
+ /* frequency */
+ uint32_t freq;
+ /* bandwidth */
+ uint8_t bandwidth;
+ /* hierarchy selection */
+ uint8_t hier_select;
+ /* constellation */
+ uint8_t modulation;
+ /* hierarchy */
+ uint8_t hierarchy;
+ /* interleaving mode */
+ uint8_t interleaving_mode;
+ /* code rate */
+ uint8_t code_rate;
+ /* guard interval */
+ uint8_t guard_interval;
+ /* transmission mode */
+ uint8_t transmission_mode;
+} __packed;
+
+struct as10x_tune_status {
+ /* tune status */
+ uint8_t tune_state;
+ /* signal strength */
+ int16_t signal_strength;
+ /* packet error rate 10^-4 */
+ uint16_t PER;
+ /* bit error rate 10^-4 */
+ uint16_t BER;
+} __packed;
+
+struct as10x_demod_stats {
+ /* frame counter */
+ uint32_t frame_count;
+ /* Bad frame counter */
+ uint32_t bad_frame_count;
+ /* Number of wrong bytes fixed by Reed-Solomon */
+ uint32_t bytes_fixed_by_rs;
+ /* Averaged MER */
+ uint16_t mer;
+ /* statistics calculation state indicator (started or not) */
+ uint8_t has_started;
+} __packed;
+
+struct as10x_ts_filter {
+ uint16_t pid; /* valid PID value 0x00 : 0x2000 */
+ uint8_t type; /* Red TS_PID_TYPE_<N> values */
+ uint8_t idx; /* index in filtering table */
+} __packed;
+
+struct as10x_register_value {
+ uint8_t mode;
+ union {
+ uint8_t value8; /* 8 bit value */
+ uint16_t value16; /* 16 bit value */
+ uint32_t value32; /* 32 bit value */
+ } __packed u;
+} __packed;
+
+struct as10x_register_addr {
+ /* register addr */
+ uint32_t addr;
+ /* register mode access */
+ uint8_t mode;
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
index 39a29dd..638c7aa 100644
--- a/drivers/media/dvb-frontends/bcm3510.c
+++ b/drivers/media/dvb-frontends/bcm3510.c
@@ -639,12 +639,12 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
return ret;
}
- deb_info("got firmware: %zd\n",fw->size);
+ deb_info("got firmware: %zu\n", fw->size);
b = fw->data;
for (i = 0; i < fw->size;) {
- addr = le16_to_cpu( *( (u16 *)&b[i] ) );
- len = le16_to_cpu( *( (u16 *)&b[i+2] ) );
+ addr = le16_to_cpu(*((__le16 *)&b[i]));
+ len = le16_to_cpu(*((__le16 *)&b[i+2]));
deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
err("firmware download failed: %d\n",ret);
diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c
index 0f4657e..149fdca 100644
--- a/drivers/media/dvb-frontends/cxd2820r_c.c
+++ b/drivers/media/dvb-frontends/cxd2820r_c.c
@@ -65,7 +65,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
}
priv->delivery_system = SYS_DVBC_ANNEX_A;
- priv->ber_running = 0; /* tune stops BER counter */
+ priv->ber_running = false; /* tune stops BER counter */
/* program IF frequency */
if (fe->ops.tuner_ops.get_if_frequency) {
@@ -168,7 +168,7 @@ int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
start_ber = 1;
}
} else {
- priv->ber_running = 1;
+ priv->ber_running = true;
start_ber = 1;
}
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c
index 03930d5..cd2af3e 100644
--- a/drivers/media/dvb-frontends/cxd2820r_core.c
+++ b/drivers/media/dvb-frontends/cxd2820r_core.c
@@ -564,10 +564,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
/* check if we have a valid signal */
if (status & FE_HAS_LOCK) {
- priv->last_tune_failed = 0;
+ priv->last_tune_failed = false;
return DVBFE_ALGO_SEARCH_SUCCESS;
} else {
- priv->last_tune_failed = 1;
+ priv->last_tune_failed = true;
return DVBFE_ALGO_SEARCH_AGAIN;
}
diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c
index 9b5a45b..51401d0 100644
--- a/drivers/media/dvb-frontends/cxd2820r_t.c
+++ b/drivers/media/dvb-frontends/cxd2820r_t.c
@@ -89,7 +89,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
}
priv->delivery_system = SYS_DVBT;
- priv->ber_running = 0; /* tune stops BER counter */
+ priv->ber_running = false; /* tune stops BER counter */
/* program IF frequency */
if (fe->ops.tuner_ops.get_if_frequency) {
@@ -272,7 +272,7 @@ int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
start_ber = 1;
}
} else {
- priv->ber_running = 1;
+ priv->ber_running = true;
start_ber = 1;
}
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index 661760d..589134e 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -2559,7 +2559,7 @@ static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
dib7000p_write_word(state, 1288, reg_1288);
}
-int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
+static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 reg_1287;
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 7ca7a21..5ec221f 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -2174,7 +2174,7 @@ int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
u32 addr,
u32 *data, u32 flags)
{
- u8 buf[sizeof(*data)];
+ u8 buf[sizeof(*data)] = { 0 };
int rc = -EIO;
u32 word = 0;
@@ -4193,7 +4193,7 @@ int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
u32 addr,
u16 *data, u32 flags)
{
- u8 buf[2];
+ u8 buf[2] = { 0 };
int rc = -EIO;
u16 word = 0;
@@ -10667,7 +10667,7 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
enum drx_standard standard = ext_attr->standard;
int rc;
u32 ber, cnt, err, pkt;
- u16 mer, strength;
+ u16 mer, strength = 0;
rc = get_sig_strength(demod, &strength);
if (rc < 0) {
@@ -11602,7 +11602,7 @@ static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
u32 carry = 0;
while (i < nr_words) {
- crc_word |= (u32)be16_to_cpu(*(u32 *)(block_data));
+ crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
for (j = 0; j < 16; j++) {
crc_word <<= 1;
if (carry != 0)
@@ -11629,7 +11629,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
int i;
unsigned count = 2 * sizeof(u16);
u32 mc_dev_type, mc_version, mc_base_version;
- u16 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data + sizeof(u16)));
+ u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
/*
* Scan microcode blocks first for version info
@@ -11647,13 +11647,13 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
goto eof;
/* Process block header */
- block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data + count));
+ block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
count += sizeof(u32);
- block_hdr.size = be16_to_cpu(*(u32 *)(mc_data + count));
+ block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
count += sizeof(u16);
- block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data + count));
+ block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
count += sizeof(u16);
- block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data + count));
+ block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
count += sizeof(u16);
pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
@@ -11667,7 +11667,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
if (block_hdr.addr + sizeof(u16) > size)
goto eof;
- auxtype = be16_to_cpu(*(u32 *)(auxblk));
+ auxtype = be16_to_cpu(*(__be16 *)(auxblk));
/* Aux block. Check type */
if (DRX_ISMCVERTYPE(auxtype)) {
@@ -11675,11 +11675,11 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
goto eof;
auxblk += sizeof(u16);
- mc_dev_type = be32_to_cpu(*(u32 *)(auxblk));
+ mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
auxblk += sizeof(u32);
- mc_version = be32_to_cpu(*(u32 *)(auxblk));
+ mc_version = be32_to_cpu(*(__be32 *)(auxblk));
auxblk += sizeof(u32);
- mc_base_version = be32_to_cpu(*(u32 *)(auxblk));
+ mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
@@ -11765,9 +11765,9 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
mc_data = (void *)mc_data_init;
/* Check data */
- mc_magic_word = be16_to_cpu(*(u32 *)(mc_data));
+ mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
- mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data));
+ mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
@@ -11791,13 +11791,13 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
u16 mc_block_nr_bytes = 0;
/* Process block header */
- block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data));
+ block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
mc_data += sizeof(u32);
- block_hdr.size = be16_to_cpu(*(u32 *)(mc_data));
+ block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
- block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data));
+ block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
- block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data));
+ block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index ae2276d..687e893 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -2628,10 +2628,11 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
break;
/* Apply I2c address patch to B1 */
- if (!state->type_A && state->m_HiI2cPatch != NULL)
+ if (!state->type_A && state->m_HiI2cPatch != NULL) {
status = WriteTable(state, state->m_HiI2cPatch);
if (status < 0)
break;
+ }
if (state->type_A) {
/* HI firmware patch for UIO readout,
@@ -2830,14 +2831,8 @@ static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
static int drxd_init(struct dvb_frontend *fe)
{
struct drxd_state *state = fe->demodulator_priv;
- int err = 0;
-/* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
return DRXD_init(state, NULL, 0);
-
- err = DRXD_init(state, state->fw->data, state->fw->size);
- release_firmware(state->fw);
- return err;
}
static int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index cce94a7..6721951 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -1028,7 +1028,7 @@ static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
((state->m_hi_cfg_ctrl) &
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
- if (powerdown_cmd == false) {
+ if (!powerdown_cmd) {
/* Wait until command rdy */
u32 retry_count = 0;
u16 wait_cmd;
@@ -1129,7 +1129,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
if (status < 0)
goto error;
- if (mpeg_enable == false) {
+ if (!mpeg_enable) {
/* Set MPEG TS pads to inputmode */
status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
if (status < 0)
@@ -1190,7 +1190,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
if (status < 0)
goto error;
- if (state->m_enable_parallel == true) {
+ if (state->m_enable_parallel) {
/* parallel -> enable MD1 to MD7 */
status = write16(state, SIO_PDR_MD1_CFG__A,
sio_pdr_mdx_cfg);
@@ -1392,7 +1392,7 @@ static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
dprintk(1, "\n");
- if (enable == false) {
+ if (!enable) {
desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
}
@@ -2012,7 +2012,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
goto error;
fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
- if (state->m_insert_rs_byte == true) {
+ if (state->m_insert_rs_byte) {
/* enable parity symbol forward */
fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
/* MVAL disable during parity bytes */
@@ -2023,7 +2023,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
/* Check serial or parallel output */
fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
- if (state->m_enable_parallel == false) {
+ if (!state->m_enable_parallel) {
/* MPEG data output is serial -> set ipr_mode[0] */
fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
}
@@ -2136,19 +2136,19 @@ static int mpegts_configure_polarity(struct drxk_state *state)
/* Control selective inversion of output bits */
fec_oc_reg_ipr_invert &= (~(invert_data_mask));
- if (state->m_invert_data == true)
+ if (state->m_invert_data)
fec_oc_reg_ipr_invert |= invert_data_mask;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
- if (state->m_invert_err == true)
+ if (state->m_invert_err)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
- if (state->m_invert_str == true)
+ if (state->m_invert_str)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
- if (state->m_invert_val == true)
+ if (state->m_invert_val)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
- if (state->m_invert_clk == true)
+ if (state->m_invert_clk)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
@@ -2220,12 +2220,13 @@ static int set_agc_rf(struct drxk_state *state,
}
/* Set TOP, only if IF-AGC is in AUTO mode */
- if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
+ if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
status = write16(state,
SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
p_agc_cfg->top);
if (status < 0)
goto error;
+ }
/* Cut-Off current */
status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
@@ -3352,7 +3353,7 @@ static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
int status;
dprintk(1, "\n");
- if (*enabled == true)
+ if (*enabled)
status = write16(state, IQM_CF_BYPASSDET__A, 0);
else
status = write16(state, IQM_CF_BYPASSDET__A, 1);
@@ -3368,7 +3369,7 @@ static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
int status;
dprintk(1, "\n");
- if (*enabled == true) {
+ if (*enabled) {
/* write mask to 1 */
status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
DEFAULT_FR_THRES_8K);
@@ -6794,11 +6795,11 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
state->enable_merr_cfg = config->enable_merr_cfg;
if (config->dynamic_clk) {
- state->m_dvbt_static_clk = 0;
- state->m_dvbc_static_clk = 0;
+ state->m_dvbt_static_clk = false;
+ state->m_dvbc_static_clk = false;
} else {
- state->m_dvbt_static_clk = 1;
- state->m_dvbc_static_clk = 1;
+ state->m_dvbt_static_clk = true;
+ state->m_dvbc_static_clk = true;
}
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index dfe0c2f..81657e9 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -159,6 +159,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv,
{
int ret, i, j;
u8 buf[83];
+
dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
if (tab_len > 83) {
@@ -247,8 +248,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
u8 u8tmp, u8tmp1, u8tmp2;
u8 buf[2];
u16 u16tmp, divide_ratio;
- u32 tuner_frequency, target_mclk, ts_clk;
+ u32 tuner_frequency, target_mclk;
s32 s32tmp;
+
dev_dbg(&priv->i2c->dev,
"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
__func__, c->delivery_system,
@@ -316,9 +318,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
target_mclk = 144000;
break;
case M88DS3103_TS_PARALLEL:
- case M88DS3103_TS_PARALLEL_12:
- case M88DS3103_TS_PARALLEL_16:
- case M88DS3103_TS_PARALLEL_19_2:
case M88DS3103_TS_CI:
if (c->symbol_rate < 18000000)
target_mclk = 96000;
@@ -352,33 +351,17 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
switch (priv->cfg->ts_mode) {
case M88DS3103_TS_SERIAL:
u8tmp1 = 0x00;
- ts_clk = 0;
- u8tmp = 0x46;
+ u8tmp = 0x06;
break;
case M88DS3103_TS_SERIAL_D7:
u8tmp1 = 0x20;
- ts_clk = 0;
- u8tmp = 0x46;
+ u8tmp = 0x06;
break;
case M88DS3103_TS_PARALLEL:
- ts_clk = 24000;
- u8tmp = 0x42;
- break;
- case M88DS3103_TS_PARALLEL_12:
- ts_clk = 12000;
- u8tmp = 0x42;
- break;
- case M88DS3103_TS_PARALLEL_16:
- ts_clk = 16000;
- u8tmp = 0x42;
- break;
- case M88DS3103_TS_PARALLEL_19_2:
- ts_clk = 19200;
- u8tmp = 0x42;
+ u8tmp = 0x02;
break;
case M88DS3103_TS_CI:
- ts_clk = 6000;
- u8tmp = 0x43;
+ u8tmp = 0x03;
break;
default:
dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__);
@@ -386,6 +369,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
goto err;
}
+ if (priv->cfg->ts_clk_pol)
+ u8tmp |= 0x40;
+
/* TS mode */
ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp);
if (ret)
@@ -399,8 +385,8 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
goto err;
}
- if (ts_clk) {
- divide_ratio = DIV_ROUND_UP(target_mclk, ts_clk);
+ if (priv->cfg->ts_clk) {
+ divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk);
u8tmp1 = divide_ratio / 2;
u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
} else {
@@ -411,7 +397,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
dev_dbg(&priv->i2c->dev,
"%s: target_mclk=%d ts_clk=%d divide_ratio=%d\n",
- __func__, target_mclk, ts_clk, divide_ratio);
+ __func__, target_mclk, priv->cfg->ts_clk, divide_ratio);
u8tmp1--;
u8tmp2--;
@@ -536,6 +522,7 @@ static int m88ds3103_init(struct dvb_frontend *fe)
const struct firmware *fw = NULL;
u8 *fw_file = M88DS3103_FIRMWARE;
u8 u8tmp;
+
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
/* set cold state by default */
@@ -648,6 +635,7 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret;
+
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
priv->delivery_system = SYS_UNDEFINED;
@@ -682,6 +670,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
u8 buf[3];
+
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
@@ -857,6 +846,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
u8 buf[3];
u16 noise, signal;
u32 noise_tot, signal_tot;
+
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
/* reports SNR in resolution of 0.1 dB */
@@ -933,6 +923,7 @@ static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
int ret;
unsigned int utmp;
u8 buf[3], u8tmp;
+
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
switch (c->delivery_system) {
@@ -1013,6 +1004,7 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret;
u8 u8tmp, tone, reg_a1_mask;
+
dev_dbg(&priv->i2c->dev, "%s: fe_sec_tone_mode=%d\n", __func__,
fe_sec_tone_mode);
@@ -1053,12 +1045,64 @@ err:
return ret;
}
+static int m88ds3103_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t fe_sec_voltage)
+{
+ struct m88ds3103_priv *priv = fe->demodulator_priv;
+ int ret;
+ u8 u8tmp;
+ bool voltage_sel, voltage_dis;
+
+ dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
+ fe_sec_voltage);
+
+ if (!priv->warm) {
+ ret = -EAGAIN;
+ goto err;
+ }
+
+ switch (fe_sec_voltage) {
+ case SEC_VOLTAGE_18:
+ voltage_sel = true;
+ voltage_dis = false;
+ break;
+ case SEC_VOLTAGE_13:
+ voltage_sel = false;
+ voltage_dis = false;
+ break;
+ case SEC_VOLTAGE_OFF:
+ voltage_sel = false;
+ voltage_dis = true;
+ break;
+ default:
+ dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* output pin polarity */
+ voltage_sel ^= priv->cfg->lnb_hv_pol;
+ voltage_dis ^= priv->cfg->lnb_en_pol;
+
+ u8tmp = voltage_dis << 1 | voltage_sel << 0;
+ ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0x03);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *diseqc_cmd)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret, i;
u8 u8tmp;
+
dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__,
diseqc_cmd->msg_len, diseqc_cmd->msg);
@@ -1130,6 +1174,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret, i;
u8 u8tmp, burst;
+
dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
fe_sec_mini_cmd);
@@ -1202,6 +1247,7 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
static void m88ds3103_release(struct dvb_frontend *fe)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
+
i2c_del_mux_adapter(priv->i2c_adapter);
kfree(priv);
}
@@ -1370,6 +1416,7 @@ static struct dvb_frontend_ops m88ds3103_ops = {
.diseqc_send_burst = m88ds3103_diseqc_send_burst,
.set_tone = m88ds3103_set_tone,
+ .set_voltage = m88ds3103_set_voltage,
};
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h
index bbb7e3a..9b3b496 100644
--- a/drivers/media/dvb-frontends/m88ds3103.h
+++ b/drivers/media/dvb-frontends/m88ds3103.h
@@ -47,14 +47,23 @@ struct m88ds3103_config {
*/
#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */
#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */
-#define M88DS3103_TS_PARALLEL 2 /* 24 MHz, normal */
-#define M88DS3103_TS_PARALLEL_12 3 /* 12 MHz */
-#define M88DS3103_TS_PARALLEL_16 4 /* 16 MHz */
-#define M88DS3103_TS_PARALLEL_19_2 5 /* 19.2 MHz */
-#define M88DS3103_TS_CI 6 /* 6 MHz */
+#define M88DS3103_TS_PARALLEL 2 /* TS Parallel mode */
+#define M88DS3103_TS_CI 3 /* TS CI Mode */
u8 ts_mode;
/*
+ * TS clk in KHz
+ * Default: 0.
+ */
+ u32 ts_clk;
+
+ /*
+ * TS clk polarity.
+ * Default: 0. 1-active at falling edge; 0-active at rising edge.
+ */
+ u8 ts_clk_pol:1;
+
+ /*
* spectrum inversion
* Default: 0
*/
@@ -86,6 +95,22 @@ struct m88ds3103_config {
* Default: none, must set
*/
u8 agc;
+
+ /*
+ * LNB H/V pin polarity
+ * Default: 0.
+ * 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18.
+ * 0: pin high set to VOLTAGE_18, pin low to set VOLTAGE_13.
+ */
+ u8 lnb_hv_pol:1;
+
+ /*
+ * LNB enable pin polarity
+ * Default: 0.
+ * 1: pin high to enable, pin low to disable.
+ * 0: pin high to disable, pin low to enable.
+ */
+ u8 lnb_en_pol:1;
};
/*
diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c
index 9ae40ab..3ddea44 100644
--- a/drivers/media/dvb-frontends/mb86a16.c
+++ b/drivers/media/dvb-frontends/mb86a16.c
@@ -28,7 +28,7 @@
#include "mb86a16.h"
#include "mb86a16_priv.h"
-unsigned int verbose = 5;
+static unsigned int verbose = 5;
module_param(verbose, int, 0644);
#define ABS(x) ((x) < 0 ? (-x) : (x))
@@ -115,9 +115,11 @@ static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
};
ret = i2c_transfer(state->i2c_adap, msg, 2);
if (ret != 2) {
- dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
+ dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=%i)",
reg, ret);
+ if (ret < 0)
+ return ret;
return -EREMOTEIO;
}
*val = b1[0];
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index b931179..e6f165a 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -33,7 +33,7 @@ enum mb86a20s_bandwidth {
MB86A20S_3SEG = 3,
};
-u8 mb86a20s_subchannel[] = {
+static u8 mb86a20s_subchannel[] = {
0xb0, 0xc0, 0xd0, 0xe0,
0xf0, 0x00, 0x10, 0x20,
};
@@ -1228,7 +1228,7 @@ struct linear_segments {
* All tables below return a dB/1000 measurement
*/
-static struct linear_segments cnr_to_db_table[] = {
+static const struct linear_segments cnr_to_db_table[] = {
{ 19648, 0},
{ 18187, 1000},
{ 16534, 2000},
@@ -1262,7 +1262,7 @@ static struct linear_segments cnr_to_db_table[] = {
{ 788, 30000},
};
-static struct linear_segments cnr_64qam_table[] = {
+static const struct linear_segments cnr_64qam_table[] = {
{ 3922688, 0},
{ 3920384, 1000},
{ 3902720, 2000},
@@ -1296,7 +1296,7 @@ static struct linear_segments cnr_64qam_table[] = {
{ 388864, 30000},
};
-static struct linear_segments cnr_16qam_table[] = {
+static const struct linear_segments cnr_16qam_table[] = {
{ 5314816, 0},
{ 5219072, 1000},
{ 5118720, 2000},
@@ -1330,7 +1330,7 @@ static struct linear_segments cnr_16qam_table[] = {
{ 95744, 30000},
};
-struct linear_segments cnr_qpsk_table[] = {
+static const struct linear_segments cnr_qpsk_table[] = {
{ 2834176, 0},
{ 2683648, 1000},
{ 2536960, 2000},
@@ -1364,7 +1364,7 @@ struct linear_segments cnr_qpsk_table[] = {
{ 11520, 30000},
};
-static u32 interpolate_value(u32 value, struct linear_segments *segments,
+static u32 interpolate_value(u32 value, const struct linear_segments *segments,
unsigned len)
{
u64 tmp64;
@@ -1448,7 +1448,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u32 mer, cnr;
int rc, val, layer;
- struct linear_segments *segs;
+ const struct linear_segments *segs;
unsigned segs_len;
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
index a74ac0d..2163490 100644
--- a/drivers/media/dvb-frontends/mt312.c
+++ b/drivers/media/dvb-frontends/mt312.c
@@ -103,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
if (1 + count > sizeof(buf)) {
printk(KERN_WARNING
- "mt312: write: len=%zd is too big!\n", count);
+ "mt312: write: len=%zu is too big!\n", count);
return -EINVAL;
}
diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c
index 10cfc05..873ea1d 100644
--- a/drivers/media/dvb-frontends/or51211.c
+++ b/drivers/media/dvb-frontends/or51211.c
@@ -111,7 +111,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe,
u8 tudata[585];
int i;
- dprintk("Firmware is %zd bytes\n",fw->size);
+ dprintk("Firmware is %zu bytes\n", fw->size);
/* Get eprom data */
tudata[0] = 17;
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index fdbed35..eb737cf 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -936,7 +936,7 @@ static void rtl2832_i2c_gate_work(struct work_struct *work)
if (ret != 1)
goto err;
- priv->i2c_gate_state = 0;
+ priv->i2c_gate_state = false;
return;
err:
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index 023e0f4..7bf98cf 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -329,7 +329,7 @@ static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
struct rtl2832_sdr_state *s)
{
- unsigned long flags = 0;
+ unsigned long flags;
struct rtl2832_sdr_frame_buf *buf = NULL;
spin_lock_irqsave(&s->queued_bufs_lock, flags);
@@ -365,17 +365,19 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
dst_len = 0;
}
- /* calculate samping rate and output it in 10 seconds intervals */
+ /* calculate sample rate and output it in 10 seconds intervals */
if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
+ #define MSECS 10000UL
+ unsigned int msecs = jiffies_to_msecs(jiffies -
+ s->jiffies_next + msecs_to_jiffies(MSECS));
unsigned int samples = s->sample - s->sample_measured;
s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
s->sample_measured = s->sample;
dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, MSECS,
- samples * 1000UL / MSECS);
+ "slen=%u samples=%u msecs=%u sample rate=%lu\n",
+ src_len, samples, msecs,
+ samples * 1000UL / msecs);
}
/* total number of I+Q pairs */
@@ -394,8 +396,8 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
struct rtl2832_sdr_frame_buf *fbuf;
dev_dbg_ratelimited(&s->udev->dev,
- "%s: status=%d length=%d/%d errors=%d\n",
- __func__, urb->status, urb->actual_length,
+ "status=%d length=%d/%d errors=%d\n",
+ urb->status, urb->actual_length,
urb->transfer_buffer_length, urb->error_count);
switch (urb->status) {
@@ -443,7 +445,7 @@ static int rtl2832_sdr_kill_urbs(struct rtl2832_sdr_state *s)
int i;
for (i = s->urbs_submitted - 1; i >= 0; i--) {
- dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
+ dev_dbg(&s->udev->dev, "kill urb=%d\n", i);
/* stop the URB */
usb_kill_urb(s->urb_list[i]);
}
@@ -457,7 +459,7 @@ static int rtl2832_sdr_submit_urbs(struct rtl2832_sdr_state *s)
int i, ret;
for (i = 0; i < s->urbs_initialized; i++) {
- dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
+ dev_dbg(&s->udev->dev, "submit urb=%d\n", i);
ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
if (ret) {
dev_err(&s->udev->dev,
@@ -477,8 +479,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_state *s)
if (s->flags & USB_STATE_URB_BUF) {
while (s->buf_num) {
s->buf_num--;
- dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
- __func__, s->buf_num);
+ dev_dbg(&s->udev->dev, "free buf=%d\n", s->buf_num);
usb_free_coherent(s->udev, s->buf_size,
s->buf_list[s->buf_num],
s->dma_addr[s->buf_num]);
@@ -494,24 +495,22 @@ static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_state *s)
s->buf_num = 0;
s->buf_size = BULK_BUFFER_SIZE;
- dev_dbg(&s->udev->dev,
- "%s: all in all I will use %u bytes for streaming\n",
- __func__, MAX_BULK_BUFS * BULK_BUFFER_SIZE);
+ dev_dbg(&s->udev->dev, "all in all I will use %u bytes for streaming\n",
+ MAX_BULK_BUFS * BULK_BUFFER_SIZE);
for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
BULK_BUFFER_SIZE, GFP_ATOMIC,
&s->dma_addr[s->buf_num]);
if (!s->buf_list[s->buf_num]) {
- dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
- __func__, s->buf_num);
+ dev_dbg(&s->udev->dev, "alloc buf=%d failed\n",
+ s->buf_num);
rtl2832_sdr_free_stream_bufs(s);
return -ENOMEM;
}
- dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
- __func__, s->buf_num,
- s->buf_list[s->buf_num],
+ dev_dbg(&s->udev->dev, "alloc buf=%d %p (dma %llu)\n",
+ s->buf_num, s->buf_list[s->buf_num],
(long long)s->dma_addr[s->buf_num]);
s->flags |= USB_STATE_URB_BUF;
}
@@ -527,8 +526,7 @@ static int rtl2832_sdr_free_urbs(struct rtl2832_sdr_state *s)
for (i = s->urbs_initialized - 1; i >= 0; i--) {
if (s->urb_list[i]) {
- dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
- __func__, i);
+ dev_dbg(&s->udev->dev, "free urb=%d\n", i);
/* free the URBs */
usb_free_urb(s->urb_list[i]);
}
@@ -544,10 +542,10 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
/* allocate the URBs */
for (i = 0; i < MAX_BULK_BUFS; i++) {
- dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+ dev_dbg(&s->udev->dev, "alloc urb=%d\n", i);
s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
if (!s->urb_list[i]) {
- dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
+ dev_dbg(&s->udev->dev, "failed\n");
for (j = 0; j < i; j++)
usb_free_urb(s->urb_list[j]);
return -ENOMEM;
@@ -570,9 +568,9 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
/* Must be called with vb_queue_lock hold */
static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
{
- unsigned long flags = 0;
+ unsigned long flags;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
spin_lock_irqsave(&s->queued_bufs_lock, flags);
while (!list_empty(&s->queued_bufs)) {
@@ -591,7 +589,7 @@ static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
{
struct rtl2832_sdr_state *s = fe->sec_priv;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
mutex_lock(&s->vb_queue_lock);
mutex_lock(&s->v4l2_lock);
@@ -613,7 +611,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
@@ -631,15 +629,15 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
- dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
+ dev_dbg(&s->udev->dev, "nbuffers=%d\n", *nbuffers);
/* Need at least 8 buffers */
if (vq->num_buffers + *nbuffers < 8)
*nbuffers = 8 - vq->num_buffers;
*nplanes = 1;
sizes[0] = PAGE_ALIGN(s->buffersize);
- dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
- __func__, *nbuffers, sizes[0]);
+ dev_dbg(&s->udev->dev, "nbuffers=%d sizes[0]=%d\n",
+ *nbuffers, sizes[0]);
return 0;
}
@@ -659,7 +657,7 @@ static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
struct rtl2832_sdr_frame_buf *buf =
container_of(vb, struct rtl2832_sdr_frame_buf, vb);
- unsigned long flags = 0;
+ unsigned long flags;
/* Check the device has not disconnected between prep and queuing */
if (!s->udev) {
@@ -681,7 +679,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u64 u64tmp;
u32 u32tmp;
- dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
+ dev_dbg(&s->udev->dev, "f_adc=%u\n", s->f_adc);
if (!test_bit(POWER_ON, &s->flags))
return 0;
@@ -715,8 +713,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u64tmp = -u64tmp;
u32tmp = u64tmp & 0x3fffff;
- dev_dbg(&s->udev->dev, "%s: f_if=%u if_ctl=%08x\n",
- __func__, f_if, u32tmp);
+ dev_dbg(&s->udev->dev, "f_if=%u if_ctl=%08x\n", f_if, u32tmp);
buf[0] = (u32tmp >> 16) & 0xff;
buf[1] = (u32tmp >> 8) & 0xff;
@@ -903,7 +900,7 @@ static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_state *s)
{
int ret;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
/* PID filter */
ret = rtl2832_sdr_wr_regs(s, 0x061, "\xe0", 1);
@@ -964,8 +961,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
c->frequency = s->f_tuner;
c->delivery_system = SYS_DVBT;
- dev_dbg(&s->udev->dev, "%s: frequency=%u bandwidth=%d\n",
- __func__, c->frequency, c->bandwidth_hz);
+ dev_dbg(&s->udev->dev, "frequency=%u bandwidth=%d\n",
+ c->frequency, c->bandwidth_hz);
if (!test_bit(POWER_ON, &s->flags))
return 0;
@@ -980,7 +977,7 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
{
struct dvb_frontend *fe = s->fe;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
if (fe->ops.tuner_ops.init)
fe->ops.tuner_ops.init(fe);
@@ -992,7 +989,7 @@ static void rtl2832_sdr_unset_tuner(struct rtl2832_sdr_state *s)
{
struct dvb_frontend *fe = s->fe;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
if (fe->ops.tuner_ops.sleep)
fe->ops.tuner_ops.sleep(fe);
@@ -1005,7 +1002,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
int ret;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
if (!s->udev)
return -ENODEV;
@@ -1054,7 +1051,7 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
mutex_lock(&s->v4l2_lock);
@@ -1088,8 +1085,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
- __func__, v->index, v->type);
+ dev_dbg(&s->udev->dev, "index=%d type=%d\n", v->index, v->type);
if (v->index == 0) {
strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
@@ -1115,7 +1111,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
if (v->index > 1)
return -EINVAL;
@@ -1127,8 +1123,8 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
- __func__, band->tuner, band->type, band->index);
+ dev_dbg(&s->udev->dev, "tuner=%d type=%d index=%d\n",
+ band->tuner, band->type, band->index);
if (band->tuner == 0) {
if (band->index >= ARRAY_SIZE(bands_adc))
@@ -1153,8 +1149,8 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
int ret = 0;
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
- __func__, f->tuner, f->type);
+ dev_dbg(&s->udev->dev, "tuner=%d type=%d\n",
+ f->tuner, f->type);
if (f->tuner == 0) {
f->frequency = s->f_adc;
@@ -1175,8 +1171,8 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
int ret, band;
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
- __func__, f->tuner, f->type, f->frequency);
+ dev_dbg(&s->udev->dev, "tuner=%d type=%d frequency=%u\n",
+ f->tuner, f->type, f->frequency);
/* ADC band midpoints */
#define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
@@ -1194,15 +1190,13 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
bands_adc[band].rangelow,
bands_adc[band].rangehigh);
- dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
- __func__, s->f_adc);
+ dev_dbg(&s->udev->dev, "ADC frequency=%u Hz\n", s->f_adc);
ret = rtl2832_sdr_set_adc(s);
} else if (f->tuner == 1) {
s->f_tuner = clamp_t(unsigned int, f->frequency,
bands_fm[0].rangelow,
bands_fm[0].rangehigh);
- dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
- __func__, f->frequency);
+ dev_dbg(&s->udev->dev, "RF frequency=%u Hz\n", f->frequency);
ret = rtl2832_sdr_set_tuner_freq(s);
} else {
@@ -1217,7 +1211,7 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
if (f->index >= s->num_formats)
return -EINVAL;
@@ -1233,7 +1227,7 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "\n");
f->fmt.sdr.pixelformat = s->pixelformat;
f->fmt.sdr.buffersize = s->buffersize;
@@ -1250,7 +1244,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
struct vb2_queue *q = &s->vb_queue;
int i;
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ dev_dbg(&s->udev->dev, "pixelformat fourcc %4.4s\n",
(char *)&f->fmt.sdr.pixelformat);
if (vb2_is_busy(q))
@@ -1280,7 +1274,7 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
int i;
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ dev_dbg(&s->udev->dev, "pixelformat fourcc %4.4s\n",
(char *)&f->fmt.sdr.pixelformat);
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
@@ -1354,8 +1348,8 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
int ret;
dev_dbg(&s->udev->dev,
- "%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
- __func__, ctrl->id, ctrl->name, ctrl->val,
+ "id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
+ ctrl->id, ctrl->name, ctrl->val,
ctrl->minimum, ctrl->maximum, ctrl->step);
switch (ctrl->id) {
@@ -1432,7 +1426,7 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->pixelformat = formats[0].pixelformat;
s->buffersize = formats[0].buffersize;
s->num_formats = NUM_FORMATS;
- if (rtl2832_sdr_emulated_fmt == false)
+ if (!rtl2832_sdr_emulated_fmt)
s->num_formats -= 1;
mutex_init(&s->v4l2_lock);
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c
index 3a2d6c5..98ddb49 100644
--- a/drivers/media/dvb-frontends/si2165.c
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -1,5 +1,5 @@
/*
- Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+ Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
@@ -44,9 +44,7 @@ struct si2165_state {
struct si2165_config config;
- /* chip revision */
- u8 revcode;
- /* chip type */
+ u8 chip_revcode;
u8 chip_type;
/* calculated by xtal and div settings */
@@ -312,7 +310,7 @@ static u32 si2165_get_fe_clk(struct si2165_state *state)
return state->adc_clk;
}
-static bool si2165_wait_init_done(struct si2165_state *state)
+static int si2165_wait_init_done(struct si2165_state *state)
{
int ret = -EINVAL;
u8 val = 0;
@@ -407,7 +405,7 @@ static int si2165_upload_firmware(struct si2165_state *state)
int ret;
const struct firmware *fw = NULL;
- u8 *fw_file = SI2165_FIRMWARE;
+ u8 *fw_file;
const u8 *data;
u32 len;
u32 offset;
@@ -415,10 +413,20 @@ static int si2165_upload_firmware(struct si2165_state *state)
u8 block_count;
u16 crc_expected;
+ switch (state->chip_revcode) {
+ case 0x03: /* revision D */
+ fw_file = SI2165_FIRMWARE_REV_D;
+ break;
+ default:
+ dev_info(&state->i2c->dev, "%s: no firmware file for revision=%d\n",
+ KBUILD_MODNAME, state->chip_revcode);
+ return 0;
+ }
+
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
if (ret) {
- dev_warn(&state->i2c->dev, "%s: firmare file '%s' not found\n",
+ dev_warn(&state->i2c->dev, "%s: firmware file '%s' not found\n",
KBUILD_MODNAME, fw_file);
goto error;
}
@@ -908,7 +916,7 @@ static void si2165_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops si2165_ops = {
.info = {
- .name = "Silicon Labs Si2165",
+ .name = "Silicon Labs ",
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
@@ -948,6 +956,8 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
int n;
int io_ret;
u8 val;
+ char rev_char;
+ const char *chip_name;
if (config == NULL || i2c == NULL)
goto error;
@@ -984,7 +994,7 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
if (val != state->config.chip_mode)
goto error;
- io_ret = si2165_readreg8(state, 0x0023 , &state->revcode);
+ io_ret = si2165_readreg8(state, 0x0023, &state->chip_revcode);
if (io_ret < 0)
goto error;
@@ -997,22 +1007,35 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
if (io_ret < 0)
goto error;
- dev_info(&state->i2c->dev, "%s: hardware revision 0x%02x, chip type 0x%02x\n",
- KBUILD_MODNAME, state->revcode, state->chip_type);
+ if (state->chip_revcode < 26)
+ rev_char = 'A' + state->chip_revcode;
+ else
+ rev_char = '?';
- /* It is a guess that register 0x0118 (chip type?) can be used to
- * differ between si2161, si2163 and si2165
- * Only si2165 has been tested.
- */
- if (state->revcode == 0x03 && state->chip_type == 0x07) {
+ switch (state->chip_type) {
+ case 0x06:
+ chip_name = "Si2161";
+ state->has_dvbt = true;
+ break;
+ case 0x07:
+ chip_name = "Si2165";
state->has_dvbt = true;
state->has_dvbc = true;
- } else {
- dev_err(&state->i2c->dev, "%s: Unsupported chip.\n",
- KBUILD_MODNAME);
+ break;
+ default:
+ dev_err(&state->i2c->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n",
+ KBUILD_MODNAME, state->chip_type, state->chip_revcode);
goto error;
}
+ dev_info(&state->i2c->dev,
+ "%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n",
+ KBUILD_MODNAME, chip_name, rev_char, state->chip_type,
+ state->chip_revcode);
+
+ strlcat(state->frontend.ops.info.name, chip_name,
+ sizeof(state->frontend.ops.info.name));
+
n = 0;
if (state->has_dvbt) {
state->frontend.ops.delsys[n++] = SYS_DVBT;
@@ -1037,4 +1060,4 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(SI2165_FIRMWARE);
+MODULE_FIRMWARE(SI2165_FIRMWARE_REV_D);
diff --git a/drivers/media/dvb-frontends/si2165_priv.h b/drivers/media/dvb-frontends/si2165_priv.h
index d4cc93f..2b70cf1 100644
--- a/drivers/media/dvb-frontends/si2165_priv.h
+++ b/drivers/media/dvb-frontends/si2165_priv.h
@@ -18,6 +18,6 @@
#ifndef _DVB_SI2165_PRIV
#define _DVB_SI2165_PRIV
-#define SI2165_FIRMWARE "dvb-demod-si2165.fw"
+#define SI2165_FIRMWARE_REV_D "dvb-demod-si2165.fw"
#endif /* _DVB_SI2165_PRIV */
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 8f81d97..1cd93be 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -55,8 +55,7 @@ static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
break;
}
- dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
- __func__,
+ dev_dbg(&s->client->dev, "cmd execution took %d ms\n",
jiffies_to_msecs(jiffies) -
(jiffies_to_msecs(timeout) - TIMEOUT));
@@ -75,7 +74,7 @@ err_mutex_unlock:
return 0;
err:
- dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@@ -150,12 +149,12 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
}
- dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
- __func__, *status, cmd.rlen, cmd.args);
+ dev_dbg(&s->client->dev, "status=%02x args=%*ph\n",
+ *status, cmd.rlen, cmd.args);
return 0;
err:
- dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@@ -168,10 +167,10 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
u8 bandwidth, delivery_system;
dev_dbg(&s->client->dev,
- "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n",
- __func__, c->delivery_system, c->modulation,
+ "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u, stream_id=%d\n",
+ c->delivery_system, c->modulation,
c->frequency, c->bandwidth_hz, c->symbol_rate,
- c->inversion);
+ c->inversion, c->stream_id);
if (!s->active) {
ret = -EAGAIN;
@@ -235,6 +234,18 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
+ if (c->delivery_system == SYS_DVBT2) {
+ /* select PLP */
+ cmd.args[0] = 0x52;
+ cmd.args[1] = c->stream_id & 0xff;
+ cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1;
+ cmd.wlen = 3;
+ cmd.rlen = 1;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+ }
+
memcpy(cmd.args, "\x51\x03", 2);
cmd.wlen = 2;
cmd.rlen = 12;
@@ -297,13 +308,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
- memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 4;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
cmd.wlen = 6;
cmd.rlen = 4;
@@ -343,7 +347,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
return 0;
err:
- dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@@ -357,8 +361,9 @@ static int si2168_init(struct dvb_frontend *fe)
struct si2168_cmd cmd;
unsigned int chip_id;
- dev_dbg(&s->client->dev, "%s:\n", __func__);
+ dev_dbg(&s->client->dev, "\n");
+ /* initialize */
memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
cmd.wlen = 13;
cmd.rlen = 0;
@@ -366,6 +371,26 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret)
goto err;
+ if (s->fw_loaded) {
+ /* resume */
+ memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
+ cmd.wlen = 8;
+ cmd.rlen = 1;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
+ memcpy(cmd.args, "\x85", 1);
+ cmd.wlen = 1;
+ cmd.rlen = 1;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
+ goto warm;
+ }
+
+ /* power up */
memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
cmd.wlen = 8;
cmd.rlen = 1;
@@ -400,16 +425,16 @@ static int si2168_init(struct dvb_frontend *fe)
break;
default:
dev_err(&s->client->dev,
- "%s: unkown chip version Si21%d-%c%c%c\n",
- KBUILD_MODNAME, cmd.args[2], cmd.args[1],
+ "unknown chip version Si21%d-%c%c%c\n",
+ cmd.args[2], cmd.args[1],
cmd.args[3], cmd.args[4]);
ret = -EINVAL;
goto err;
}
/* cold state - try to download firmware */
- dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
- KBUILD_MODNAME, si2168_ops.info.name);
+ dev_info(&s->client->dev, "found a '%s' in cold state\n",
+ si2168_ops.info.name);
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, &s->client->dev);
@@ -422,18 +447,18 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret == 0) {
dev_notice(&s->client->dev,
- "%s: please install firmware file '%s'\n",
- KBUILD_MODNAME, SI2168_B40_FIRMWARE);
+ "please install firmware file '%s'\n",
+ SI2168_B40_FIRMWARE);
} else {
dev_err(&s->client->dev,
- "%s: firmware file '%s' not found\n",
- KBUILD_MODNAME, fw_file);
+ "firmware file '%s' not found\n",
+ fw_file);
goto err;
}
}
- dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
- KBUILD_MODNAME, fw_file);
+ dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
+ fw_file);
for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
len = remaining;
@@ -446,8 +471,8 @@ static int si2168_init(struct dvb_frontend *fe)
ret = si2168_cmd_execute(s, &cmd);
if (ret) {
dev_err(&s->client->dev,
- "%s: firmware download failed=%d\n",
- KBUILD_MODNAME, ret);
+ "firmware download failed=%d\n",
+ ret);
goto err;
}
}
@@ -462,8 +487,20 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret)
goto err;
- dev_info(&s->client->dev, "%s: found a '%s' in warm state\n",
- KBUILD_MODNAME, si2168_ops.info.name);
+ /* set ts mode */
+ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
+ cmd.args[4] |= s->ts_mode;
+ cmd.wlen = 6;
+ cmd.rlen = 4;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
+ s->fw_loaded = true;
+
+warm:
+ dev_info(&s->client->dev, "found a '%s' in warm state\n",
+ si2168_ops.info.name);
s->active = true;
@@ -472,7 +509,7 @@ err:
if (fw)
release_firmware(fw);
- dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@@ -482,7 +519,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
int ret;
struct si2168_cmd cmd;
- dev_dbg(&s->client->dev, "%s:\n", __func__);
+ dev_dbg(&s->client->dev, "\n");
s->active = false;
@@ -495,7 +532,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
return 0;
err:
- dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@@ -528,8 +565,7 @@ static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
/* open tuner I2C gate */
ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
if (ret != 1) {
- dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
- KBUILD_MODNAME, ret);
+ dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
if (ret >= 0)
ret = -EREMOTEIO;
} else {
@@ -553,8 +589,7 @@ static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
/* close tuner I2C gate */
ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
if (ret != 1) {
- dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
- KBUILD_MODNAME, ret);
+ dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
if (ret >= 0)
ret = -EREMOTEIO;
} else {
@@ -587,7 +622,8 @@ static const struct dvb_frontend_ops si2168_ops = {
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
- FE_CAN_2G_MODULATION
+ FE_CAN_2G_MODULATION |
+ FE_CAN_MULTISTREAM
},
.get_tune_settings = si2168_get_tune_settings,
@@ -607,12 +643,12 @@ static int si2168_probe(struct i2c_client *client,
struct si2168 *s;
int ret;
- dev_dbg(&client->dev, "%s:\n", __func__);
+ dev_dbg(&client->dev, "\n");
s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
- dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+ dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
@@ -633,16 +669,17 @@ static int si2168_probe(struct i2c_client *client,
*config->i2c_adapter = s->adapter;
*config->fe = &s->fe;
+ s->ts_mode = config->ts_mode;
+ s->fw_loaded = false;
i2c_set_clientdata(client, s);
dev_info(&s->client->dev,
- "%s: Silicon Labs Si2168 successfully attached\n",
- KBUILD_MODNAME);
+ "Silicon Labs Si2168 successfully attached\n");
return 0;
err:
kfree(s);
- dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
}
@@ -650,7 +687,7 @@ static int si2168_remove(struct i2c_client *client)
{
struct si2168 *s = i2c_get_clientdata(client);
- dev_dbg(&client->dev, "%s:\n", __func__);
+ dev_dbg(&client->dev, "\n");
i2c_del_mux_adapter(s->adapter);
diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h
index 3c5b5ab..e086d67 100644
--- a/drivers/media/dvb-frontends/si2168.h
+++ b/drivers/media/dvb-frontends/si2168.h
@@ -34,6 +34,12 @@ struct si2168_config {
* returned by driver
*/
struct i2c_adapter **i2c_adapter;
+
+ /* TS mode */
+ u8 ts_mode;
};
+#define SI2168_TS_PARALLEL 0x06
+#define SI2168_TS_SERIAL 0x03
+
#endif
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index ebbf502..e13983e 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -36,6 +36,8 @@ struct si2168 {
fe_delivery_system_t delivery_system;
fe_status_t fe_status;
bool active;
+ bool fw_loaded;
+ u8 ts_mode;
};
/* firmare command struct */
diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
index 73b47cc..16850e2 100644
--- a/drivers/media/dvb-frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -236,6 +236,9 @@ static int si21_writeregs(struct si21xx_state *state, u8 reg1,
.len = len + 1
};
+ if (len > sizeof(buf) - 1)
+ return -EINVAL;
+
msg.buf[0] = reg1;
memcpy(msg.buf + 1, data, len);
diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c
new file mode 100644
index 0000000..9b684d5
--- /dev/null
+++ b/drivers/media/dvb-frontends/sp2.c
@@ -0,0 +1,441 @@
+/*
+ * CIMaX SP2/SP2HF (Atmel T90FJR) CI driver
+ *
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
+ *
+ * Heavily based on CIMax2(R) SP2 driver in conjunction with NetUp Dual
+ * DVB-S2 CI card (cimax2) with following copyrights:
+ *
+ * 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.
+ */
+
+#include "sp2_priv.h"
+
+static int sp2_read_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
+{
+ int ret;
+ struct i2c_client *client = s->client;
+ struct i2c_adapter *adap = client->adapter;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = &reg,
+ .len = 1
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = len
+ }
+ };
+
+ ret = i2c_transfer(adap, msg, 2);
+
+ if (ret != 2) {
+ dev_err(&client->dev, "i2c read error, reg = 0x%02x, status = %d\n",
+ reg, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EIO;
+ }
+
+ dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %02x\n",
+ client->addr, reg, buf[0]);
+
+ return 0;
+}
+
+static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
+{
+ int ret;
+ u8 buffer[35];
+ struct i2c_client *client = s->client;
+ struct i2c_adapter *adap = client->adapter;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = &buffer[0],
+ .len = len + 1
+ };
+
+ if ((len + 1) > sizeof(buffer)) {
+ dev_err(&client->dev, "i2c wr reg=%02x: len=%d is too big!\n",
+ reg, len);
+ return -EINVAL;
+ }
+
+ buffer[0] = reg;
+ memcpy(&buffer[1], buf, len);
+
+ ret = i2c_transfer(adap, &msg, 1);
+
+ if (ret != 1) {
+ dev_err(&client->dev, "i2c write error, reg = 0x%02x, status = %d\n",
+ reg, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
+ u8 read, int addr, u8 data)
+{
+ struct sp2 *s = en50221->data;
+ u8 store;
+ int mem, ret;
+ int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
+
+ dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x",
+ slot, acs, addr, data);
+
+ if (slot != 0)
+ return -EINVAL;
+
+ /*
+ * change module access type between IO space and attribute memory
+ * when needed
+ */
+ if (s->module_access_type != acs) {
+ ret = sp2_read_i2c(s, 0x00, &store, 1);
+
+ if (ret)
+ return ret;
+
+ store &= ~(SP2_MOD_CTL_ACS1 | SP2_MOD_CTL_ACS0);
+ store |= acs;
+
+ ret = sp2_write_i2c(s, 0x00, &store, 1);
+ if (ret)
+ return ret;
+ }
+
+ s->module_access_type = acs;
+
+ /* implementation of ci_op_cam is device specific */
+ if (ci_op_cam) {
+ ret = ci_op_cam(s->priv, read, addr, data, &mem);
+ } else {
+ dev_err(&s->client->dev, "callback not defined");
+ return -EINVAL;
+ }
+
+ if (ret)
+ return ret;
+
+ if (read) {
+ dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x",
+ addr, mem);
+ return mem;
+ } else {
+ return 0;
+ }
+}
+
+int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr)
+{
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
+ SP2_CI_RD, addr, 0);
+}
+
+int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr, u8 data)
+{
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
+ SP2_CI_WR, addr, data);
+}
+
+int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr)
+{
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
+ SP2_CI_RD, addr, 0);
+}
+
+int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr, u8 data)
+{
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
+ SP2_CI_WR, addr, data);
+}
+
+int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct sp2 *s = en50221->data;
+ u8 buf;
+ int ret;
+
+ dev_dbg(&s->client->dev, "slot: %d\n", slot);
+
+ if (slot != 0)
+ return -EINVAL;
+
+ /* RST on */
+ buf = SP2_MOD_CTL_RST;
+ ret = sp2_write_i2c(s, 0x00, &buf, 1);
+
+ if (ret)
+ return ret;
+
+ usleep_range(500, 600);
+
+ /* RST off */
+ buf = 0x00;
+ ret = sp2_write_i2c(s, 0x00, &buf, 1);
+
+ if (ret)
+ return ret;
+
+ msleep(1000);
+
+ return 0;
+}
+
+int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct sp2 *s = en50221->data;
+
+ dev_dbg(&s->client->dev, "slot:%d\n", slot);
+
+ /* not implemented */
+ return 0;
+}
+
+int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct sp2 *s = en50221->data;
+ u8 buf;
+
+ dev_dbg(&s->client->dev, "slot:%d\n", slot);
+
+ if (slot != 0)
+ return -EINVAL;
+
+ sp2_read_i2c(s, 0x00, &buf, 1);
+
+ /* disable bypass and enable TS */
+ buf |= (SP2_MOD_CTL_TSOEN | SP2_MOD_CTL_TSIEN);
+ return sp2_write_i2c(s, 0, &buf, 1);
+}
+
+int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
+ int slot, int open)
+{
+ struct sp2 *s = en50221->data;
+ u8 buf[2];
+ int ret;
+
+ dev_dbg(&s->client->dev, "slot:%d open:%d\n", slot, open);
+
+ /*
+ * CAM module INSERT/REMOVE processing. Slow operation because of i2c
+ * transfers. Throttle read to one per sec.
+ */
+ if (time_after(jiffies, s->next_status_checked_time)) {
+ ret = sp2_read_i2c(s, 0x00, buf, 1);
+ s->next_status_checked_time = jiffies + msecs_to_jiffies(1000);
+
+ if (ret)
+ return 0;
+
+ if (buf[0] & SP2_MOD_CTL_DET)
+ s->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
+ DVB_CA_EN50221_POLL_CAM_READY;
+ else
+ s->status = 0;
+ }
+
+ return s->status;
+}
+
+int sp2_init(struct sp2 *s)
+{
+ int ret = 0;
+ u8 buf;
+ 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, 600 ns */
+ 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, 600 ns */
+ 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 control reg, VCC power on */
+ 0x00, /* RFU */
+ 0x00, /* int status read only */
+ 0x00, /* Interrupt Mask Register */
+ 0x05, /* EXTINT=active-high, INT=push-pull */
+ 0x00, /* USCG1 */
+ 0x04, /* ack active low */
+ 0x00, /* LOCK = 0 */
+ 0x22, /* unknown */
+ 0x00, /* synchronization? */
+ };
+
+ dev_dbg(&s->client->dev, "\n");
+
+ s->ca.owner = THIS_MODULE;
+ s->ca.read_attribute_mem = sp2_ci_read_attribute_mem;
+ s->ca.write_attribute_mem = sp2_ci_write_attribute_mem;
+ s->ca.read_cam_control = sp2_ci_read_cam_control;
+ s->ca.write_cam_control = sp2_ci_write_cam_control;
+ s->ca.slot_reset = sp2_ci_slot_reset;
+ s->ca.slot_shutdown = sp2_ci_slot_shutdown;
+ s->ca.slot_ts_enable = sp2_ci_slot_ts_enable;
+ s->ca.poll_slot_status = sp2_ci_poll_slot_status;
+ s->ca.data = s;
+ s->module_access_type = 0;
+
+ /* initialize all regs */
+ ret = sp2_write_i2c(s, 0x00, &cimax_init[0], 34);
+ if (ret)
+ goto err;
+
+ /* lock registers */
+ buf = 1;
+ ret = sp2_write_i2c(s, 0x1f, &buf, 1);
+ if (ret)
+ goto err;
+
+ /* power on slots */
+ ret = sp2_write_i2c(s, 0x18, &buf, 1);
+ if (ret)
+ goto err;
+
+ ret = dvb_ca_en50221_init(s->dvb_adap, &s->ca, 0, 1);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ dev_dbg(&s->client->dev, "init failed=%d\n", ret);
+ return ret;
+}
+
+int sp2_exit(struct i2c_client *client)
+{
+ struct sp2 *s;
+
+ dev_dbg(&client->dev, "\n");
+
+ if (client == NULL)
+ return 0;
+
+ s = i2c_get_clientdata(client);
+ if (s == NULL)
+ return 0;
+
+ if (s->ca.data == NULL)
+ return 0;
+
+ dvb_ca_en50221_release(&s->ca);
+
+ return 0;
+}
+
+static int sp2_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct sp2_config *cfg = client->dev.platform_data;
+ struct sp2 *s;
+ int ret;
+
+ dev_dbg(&client->dev, "\n");
+
+ s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
+ if (!s) {
+ ret = -ENOMEM;
+ dev_err(&client->dev, "kzalloc() failed\n");
+ goto err;
+ }
+
+ s->client = client;
+ s->dvb_adap = cfg->dvb_adap;
+ s->priv = cfg->priv;
+ s->ci_control = cfg->ci_control;
+
+ i2c_set_clientdata(client, s);
+
+ ret = sp2_init(s);
+ if (ret)
+ goto err;
+
+ dev_info(&s->client->dev, "CIMaX SP2 successfully attached\n");
+ return 0;
+err:
+ dev_dbg(&client->dev, "init failed=%d\n", ret);
+ kfree(s);
+
+ return ret;
+}
+
+static int sp2_remove(struct i2c_client *client)
+{
+ struct si2157 *s = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "\n");
+
+ sp2_exit(client);
+ if (s != NULL)
+ kfree(s);
+
+ return 0;
+}
+
+static const struct i2c_device_id sp2_id[] = {
+ {"sp2", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, sp2_id);
+
+static struct i2c_driver sp2_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "sp2",
+ },
+ .probe = sp2_probe,
+ .remove = sp2_remove,
+ .id_table = sp2_id,
+};
+
+module_i2c_driver(sp2_driver);
+
+MODULE_DESCRIPTION("CIMaX SP2/HF CI driver");
+MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/sp2.h b/drivers/media/dvb-frontends/sp2.h
new file mode 100644
index 0000000..6cceea0
--- /dev/null
+++ b/drivers/media/dvb-frontends/sp2.h
@@ -0,0 +1,53 @@
+/*
+ * CIMaX SP2/HF CI driver
+ *
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef SP2_H
+#define SP2_H
+
+#include <linux/kconfig.h>
+#include "dvb_ca_en50221.h"
+
+/*
+ * I2C address
+ * 0x40 (port 0)
+ * 0x41 (port 1)
+ */
+struct sp2_config {
+ /* dvb_adapter to attach the ci to */
+ struct dvb_adapter *dvb_adap;
+
+ /* function ci_control handles the device specific ci ops */
+ void *ci_control;
+
+ /* priv is passed back to function ci_control */
+ void *priv;
+};
+
+extern int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr);
+extern int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr, u8 data);
+extern int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr);
+extern int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr, u8 data);
+extern int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
+extern int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
+extern int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot);
+extern int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
+ int slot, int open);
+
+#endif
diff --git a/drivers/media/dvb-frontends/sp2_priv.h b/drivers/media/dvb-frontends/sp2_priv.h
new file mode 100644
index 0000000..37fef7b
--- /dev/null
+++ b/drivers/media/dvb-frontends/sp2_priv.h
@@ -0,0 +1,50 @@
+/*
+ * CIMaX SP2/HF CI driver
+ *
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef SP2_PRIV_H
+#define SP2_PRIV_H
+
+#include "sp2.h"
+#include "dvb_frontend.h"
+
+/* state struct */
+struct sp2 {
+ int status;
+ struct i2c_client *client;
+ struct dvb_adapter *dvb_adap;
+ struct dvb_ca_en50221 ca;
+ int module_access_type;
+ unsigned long next_status_checked_time;
+ void *priv;
+ void *ci_control;
+};
+
+#define SP2_CI_ATTR_ACS 0x00
+#define SP2_CI_IO_ACS 0x04
+#define SP2_CI_WR 0
+#define SP2_CI_RD 1
+
+/* Module control register (0x00 module A, 0x09 module B) bits */
+#define SP2_MOD_CTL_DET 0x01
+#define SP2_MOD_CTL_AUTO 0x02
+#define SP2_MOD_CTL_ACS0 0x04
+#define SP2_MOD_CTL_ACS1 0x08
+#define SP2_MOD_CTL_HAD 0x10
+#define SP2_MOD_CTL_TSIEN 0x20
+#define SP2_MOD_CTL_TSOEN 0x40
+#define SP2_MOD_CTL_RST 0x80
+
+#endif
diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c
index 2aa8ef7..57dc2aba 100644
--- a/drivers/media/dvb-frontends/sp8870.c
+++ b/drivers/media/dvb-frontends/sp8870.c
@@ -394,8 +394,7 @@ static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
if (ret < 0)
return -EIO;
- tmp = ret << 6;
-
+ tmp = ret << 6;
if (tmp >= 0x3FFF0)
tmp = ~0;
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index 59b6e66..b31ff26 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -59,7 +59,6 @@ struct stv0367cab_state {
int locked; /* channel found */
u32 freq_khz; /* found frequency (in kHz) */
u32 symbol_rate; /* found symbol rate (in Bds) */
- enum stv0367cab_mod modulation; /* modulation */
fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */
};
@@ -554,7 +553,7 @@ static struct st_register def0367ter[STV0367TER_NBREGS] = {
#define RF_LOOKUP_TABLE_SIZE 31
#define RF_LOOKUP_TABLE2_SIZE 16
/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
-s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
+static const s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
{/*AGC1*/
48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
@@ -566,7 +565,7 @@ s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
}
};
/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
-s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
+static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
{/*AGC2*/
28, 29, 31, 32, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45,
@@ -1935,8 +1934,6 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe)
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct stv0367_state *state = fe->demodulator_priv;
struct stv0367ter_state *ter_state = state->ter_state;
-
- int error = 0;
enum stv0367_ter_mode mode;
int constell = 0,/* snr = 0,*/ Data = 0;
@@ -2020,7 +2017,7 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe)
p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
- return error;
+ return 0;
}
static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
@@ -2999,7 +2996,6 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
if (QAMFEC_Lock) {
signalType = FE_CAB_DATAOK;
- cab_state->modulation = p->modulation;
cab_state->spect_inv = stv0367_readbits(state,
F367CAB_QUAD_INV);
#if 0
@@ -3165,7 +3161,7 @@ static int stv0367cab_get_frontend(struct dvb_frontend *fe)
case FE_CAB_MOD_QAM128:
p->modulation = QAM_128;
break;
- case QAM_256:
+ case FE_CAB_MOD_QAM256:
p->modulation = QAM_256;
break;
default:
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index e5a87b5..2c88abf 100644
--- a/drivers/media/dvb-frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -1270,7 +1270,6 @@ enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
enum fe_stv0900_demod_mode LDPC_Mode,
enum fe_stv0900_demod_num demod)
{
- enum fe_stv0900_error error = STV0900_NO_ERROR;
s32 reg_ind;
dprintk("%s\n", __func__);
@@ -1337,7 +1336,7 @@ enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
break;
}
- return error;
+ return STV0900_NO_ERROR;
}
static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
@@ -1555,8 +1554,6 @@ static int stv0900_status(struct stv0900_internal *intp,
static int stv0900_set_mis(struct stv0900_internal *intp,
enum fe_stv0900_demod_num demod, int mis)
{
- enum fe_stv0900_error error = STV0900_NO_ERROR;
-
dprintk("%s\n", __func__);
if (mis < 0 || mis > 255) {
@@ -1569,7 +1566,7 @@ static int stv0900_set_mis(struct stv0900_internal *intp,
stv0900_write_reg(intp, ISIBITENA, 0xff);
}
- return error;
+ return STV0900_NO_ERROR;
}
diff --git a/drivers/media/dvb-frontends/stv0900_sw.c b/drivers/media/dvb-frontends/stv0900_sw.c
index 4ce1d26..a0a7b16 100644
--- a/drivers/media/dvb-frontends/stv0900_sw.c
+++ b/drivers/media/dvb-frontends/stv0900_sw.c
@@ -1733,9 +1733,10 @@ static void stv0900_set_search_standard(struct stv0900_internal *intp,
break;
case STV0900_SEARCH_DSS:
dprintk("Search Standard = DSS\n");
- case STV0900_SEARCH_DVBS2:
break;
+ case STV0900_SEARCH_DVBS2:
dprintk("Search Standard = DVBS2\n");
+ break;
case STV0900_AUTO_SEARCH:
default:
dprintk("Search Standard = AUTO\n");
diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c
new file mode 100644
index 0000000..d9905fb
--- /dev/null
+++ b/drivers/media/dvb-frontends/tc90522.c
@@ -0,0 +1,840 @@
+/*
+ * Toshiba TC90522 Demodulator
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@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.
+ */
+
+/*
+ * NOTICE:
+ * This driver is incomplete and lacks init/config of the chips,
+ * as the necessary info is not disclosed.
+ * It assumes that users of this driver (such as a PCI bridge of
+ * DTV receiver cards) properly init and configure the chip
+ * via I2C *before* calling this driver's init() function.
+ *
+ * Currently, PT3 driver is the only one that uses this driver,
+ * and contains init/config code in its firmware.
+ * Thus some part of the code might be dependent on PT3 specific config.
+ */
+
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/dvb/frontend.h>
+#include "dvb_math.h"
+#include "tc90522.h"
+
+#define TC90522_I2C_THRU_REG 0xfe
+
+#define TC90522_MODULE_IDX(addr) (((u8)(addr) & 0x02U) >> 1)
+
+struct tc90522_state {
+ struct tc90522_config cfg;
+ struct dvb_frontend fe;
+ struct i2c_client *i2c_client;
+ struct i2c_adapter tuner_i2c;
+
+ bool lna;
+};
+
+struct reg_val {
+ u8 reg;
+ u8 val;
+};
+
+static int
+reg_write(struct tc90522_state *state, const struct reg_val *regs, int num)
+{
+ int i, ret;
+ struct i2c_msg msg;
+
+ ret = 0;
+ msg.addr = state->i2c_client->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ for (i = 0; i < num; i++) {
+ msg.buf = (u8 *)&regs[i];
+ ret = i2c_transfer(state->i2c_client->adapter, &msg, 1);
+ if (ret == 0)
+ ret = -EIO;
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int reg_read(struct tc90522_state *state, u8 reg, u8 *val, u8 len)
+{
+ struct i2c_msg msgs[2] = {
+ {
+ .addr = state->i2c_client->addr,
+ .flags = 0,
+ .buf = &reg,
+ .len = 1,
+ },
+ {
+ .addr = state->i2c_client->addr,
+ .flags = I2C_M_RD,
+ .buf = val,
+ .len = len,
+ },
+ };
+ int ret;
+
+ ret = i2c_transfer(state->i2c_client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret == ARRAY_SIZE(msgs))
+ ret = 0;
+ else if (ret >= 0)
+ ret = -EIO;
+ return ret;
+}
+
+static struct tc90522_state *cfg_to_state(struct tc90522_config *c)
+{
+ return container_of(c, struct tc90522_state, cfg);
+}
+
+
+static int tc90522s_set_tsid(struct dvb_frontend *fe)
+{
+ struct reg_val set_tsid[] = {
+ { 0x8f, 00 },
+ { 0x90, 00 }
+ };
+
+ set_tsid[0].val = (fe->dtv_property_cache.stream_id & 0xff00) >> 8;
+ set_tsid[1].val = fe->dtv_property_cache.stream_id & 0xff;
+ return reg_write(fe->demodulator_priv, set_tsid, ARRAY_SIZE(set_tsid));
+}
+
+static int tc90522t_set_layers(struct dvb_frontend *fe)
+{
+ struct reg_val rv;
+ u8 laysel;
+
+ laysel = ~fe->dtv_property_cache.isdbt_layer_enabled & 0x07;
+ laysel = (laysel & 0x01) << 2 | (laysel & 0x02) | (laysel & 0x04) >> 2;
+ rv.reg = 0x71;
+ rv.val = laysel;
+ return reg_write(fe->demodulator_priv, &rv, 1);
+}
+
+/* frontend ops */
+
+static int tc90522s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct tc90522_state *state;
+ int ret;
+ u8 reg;
+
+ state = fe->demodulator_priv;
+ ret = reg_read(state, 0xc3, &reg, 1);
+ if (ret < 0)
+ return ret;
+
+ *status = 0;
+ if (reg & 0x80) /* input level under min ? */
+ return 0;
+ *status |= FE_HAS_SIGNAL;
+
+ if (reg & 0x60) /* carrier? */
+ return 0;
+ *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
+
+ if (reg & 0x10)
+ return 0;
+ if (reg_read(state, 0xc5, &reg, 1) < 0 || !(reg & 0x03))
+ return 0;
+ *status |= FE_HAS_LOCK;
+ return 0;
+}
+
+static int tc90522t_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct tc90522_state *state;
+ int ret;
+ u8 reg;
+
+ state = fe->demodulator_priv;
+ ret = reg_read(state, 0x96, &reg, 1);
+ if (ret < 0)
+ return ret;
+
+ *status = 0;
+ if (reg & 0xe0) {
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI
+ | FE_HAS_SYNC | FE_HAS_LOCK;
+ return 0;
+ }
+
+ ret = reg_read(state, 0x80, &reg, 1);
+ if (ret < 0)
+ return ret;
+
+ if (reg & 0xf0)
+ return 0;
+ *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+ if (reg & 0x0c)
+ return 0;
+ *status |= FE_HAS_SYNC | FE_HAS_VITERBI;
+
+ if (reg & 0x02)
+ return 0;
+ *status |= FE_HAS_LOCK;
+ return 0;
+}
+
+static const fe_code_rate_t fec_conv_sat[] = {
+ FEC_NONE, /* unused */
+ FEC_1_2, /* for BPSK */
+ FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, /* for QPSK */
+ FEC_2_3, /* for 8PSK. (trellis code) */
+};
+
+static int tc90522s_get_frontend(struct dvb_frontend *fe)
+{
+ struct tc90522_state *state;
+ struct dtv_frontend_properties *c;
+ struct dtv_fe_stats *stats;
+ int ret, i;
+ int layers;
+ u8 val[10];
+ u32 cndat;
+
+ state = fe->demodulator_priv;
+ c = &fe->dtv_property_cache;
+ c->delivery_system = SYS_ISDBS;
+
+ layers = 0;
+ ret = reg_read(state, 0xe8, val, 3);
+ if (ret == 0) {
+ int slots;
+ u8 v;
+
+ /* high/single layer */
+ v = (val[0] & 0x70) >> 4;
+ c->modulation = (v == 7) ? PSK_8 : QPSK;
+ c->fec_inner = fec_conv_sat[v];
+ c->layer[0].fec = c->fec_inner;
+ c->layer[0].modulation = c->modulation;
+ c->layer[0].segment_count = val[1] & 0x3f; /* slots */
+
+ /* low layer */
+ v = (val[0] & 0x07);
+ c->layer[1].fec = fec_conv_sat[v];
+ if (v == 0) /* no low layer */
+ c->layer[1].segment_count = 0;
+ else
+ c->layer[1].segment_count = val[2] & 0x3f; /* slots */
+ /* actually, BPSK if v==1, but not defined in fe_modulation_t */
+ c->layer[1].modulation = QPSK;
+ layers = (v > 0) ? 2 : 1;
+
+ slots = c->layer[0].segment_count + c->layer[1].segment_count;
+ c->symbol_rate = 28860000 * slots / 48;
+ }
+
+ /* statistics */
+
+ stats = &c->strength;
+ stats->len = 0;
+ /* let the connected tuner set RSSI property cache */
+ if (fe->ops.tuner_ops.get_rf_strength) {
+ u16 dummy;
+
+ fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
+ }
+
+ stats = &c->cnr;
+ stats->len = 1;
+ stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ cndat = 0;
+ ret = reg_read(state, 0xbc, val, 2);
+ if (ret == 0)
+ cndat = val[0] << 8 | val[1];
+ if (cndat >= 3000) {
+ u32 p, p4;
+ s64 cn;
+
+ cndat -= 3000; /* cndat: 4.12 fixed point float */
+ /*
+ * cnr[mdB] = -1634.6 * P^5 + 14341 * P^4 - 50259 * P^3
+ * + 88977 * P^2 - 89565 * P + 58857
+ * (P = sqrt(cndat) / 64)
+ */
+ /* p := sqrt(cndat) << 8 = P << 14, 2.14 fixed point float */
+ /* cn = cnr << 3 */
+ p = int_sqrt(cndat << 16);
+ p4 = cndat * cndat;
+ cn = div64_s64(-16346LL * p4 * p, 10) >> 35;
+ cn += (14341LL * p4) >> 21;
+ cn -= (50259LL * cndat * p) >> 23;
+ cn += (88977LL * cndat) >> 9;
+ cn -= (89565LL * p) >> 11;
+ cn += 58857 << 3;
+ stats->stat[0].svalue = cn >> 3;
+ stats->stat[0].scale = FE_SCALE_DECIBEL;
+ }
+
+ /* per-layer post viterbi BER (or PER? config dependent?) */
+ stats = &c->post_bit_error;
+ memset(stats, 0, sizeof(*stats));
+ stats->len = layers;
+ ret = reg_read(state, 0xeb, val, 10);
+ if (ret < 0)
+ for (i = 0; i < layers; i++)
+ stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ else {
+ for (i = 0; i < layers; i++) {
+ stats->stat[i].scale = FE_SCALE_COUNTER;
+ stats->stat[i].uvalue = val[i * 5] << 16
+ | val[i * 5 + 1] << 8 | val[i * 5 + 2];
+ }
+ }
+ stats = &c->post_bit_count;
+ memset(stats, 0, sizeof(*stats));
+ stats->len = layers;
+ if (ret < 0)
+ for (i = 0; i < layers; i++)
+ stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ else {
+ for (i = 0; i < layers; i++) {
+ stats->stat[i].scale = FE_SCALE_COUNTER;
+ stats->stat[i].uvalue =
+ val[i * 5 + 3] << 8 | val[i * 5 + 4];
+ stats->stat[i].uvalue *= 204 * 8;
+ }
+ }
+
+ return 0;
+}
+
+
+static const fe_transmit_mode_t tm_conv[] = {
+ TRANSMISSION_MODE_2K,
+ TRANSMISSION_MODE_4K,
+ TRANSMISSION_MODE_8K,
+ 0
+};
+
+static const fe_code_rate_t fec_conv_ter[] = {
+ FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, 0, 0, 0
+};
+
+static const fe_modulation_t mod_conv[] = {
+ DQPSK, QPSK, QAM_16, QAM_64, 0, 0, 0, 0
+};
+
+static int tc90522t_get_frontend(struct dvb_frontend *fe)
+{
+ struct tc90522_state *state;
+ struct dtv_frontend_properties *c;
+ struct dtv_fe_stats *stats;
+ int ret, i;
+ int layers;
+ u8 val[15], mode;
+ u32 cndat;
+
+ state = fe->demodulator_priv;
+ c = &fe->dtv_property_cache;
+ c->delivery_system = SYS_ISDBT;
+ c->bandwidth_hz = 6000000;
+ mode = 1;
+ ret = reg_read(state, 0xb0, val, 1);
+ if (ret == 0) {
+ mode = (val[0] & 0xc0) >> 2;
+ c->transmission_mode = tm_conv[mode];
+ c->guard_interval = (val[0] & 0x30) >> 4;
+ }
+
+ ret = reg_read(state, 0xb2, val, 6);
+ layers = 0;
+ if (ret == 0) {
+ u8 v;
+
+ c->isdbt_partial_reception = val[0] & 0x01;
+ c->isdbt_sb_mode = (val[0] & 0xc0) == 0x01;
+
+ /* layer A */
+ v = (val[2] & 0x78) >> 3;
+ if (v == 0x0f)
+ c->layer[0].segment_count = 0;
+ else {
+ layers++;
+ c->layer[0].segment_count = v;
+ c->layer[0].fec = fec_conv_ter[(val[1] & 0x1c) >> 2];
+ c->layer[0].modulation = mod_conv[(val[1] & 0xe0) >> 5];
+ v = (val[1] & 0x03) << 1 | (val[2] & 0x80) >> 7;
+ c->layer[0].interleaving = v;
+ }
+
+ /* layer B */
+ v = (val[3] & 0x03) << 1 | (val[4] & 0xc0) >> 6;
+ if (v == 0x0f)
+ c->layer[1].segment_count = 0;
+ else {
+ layers++;
+ c->layer[1].segment_count = v;
+ c->layer[1].fec = fec_conv_ter[(val[3] & 0xe0) >> 5];
+ c->layer[1].modulation = mod_conv[(val[2] & 0x07)];
+ c->layer[1].interleaving = (val[3] & 0x1c) >> 2;
+ }
+
+ /* layer C */
+ v = (val[5] & 0x1e) >> 1;
+ if (v == 0x0f)
+ c->layer[2].segment_count = 0;
+ else {
+ layers++;
+ c->layer[2].segment_count = v;
+ c->layer[2].fec = fec_conv_ter[(val[4] & 0x07)];
+ c->layer[2].modulation = mod_conv[(val[4] & 0x38) >> 3];
+ c->layer[2].interleaving = (val[5] & 0xe0) >> 5;
+ }
+ }
+
+ /* statistics */
+
+ stats = &c->strength;
+ stats->len = 0;
+ /* let the connected tuner set RSSI property cache */
+ if (fe->ops.tuner_ops.get_rf_strength) {
+ u16 dummy;
+
+ fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
+ }
+
+ stats = &c->cnr;
+ stats->len = 1;
+ stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ cndat = 0;
+ ret = reg_read(state, 0x8b, val, 3);
+ if (ret == 0)
+ cndat = val[0] << 16 | val[1] << 8 | val[2];
+ if (cndat != 0) {
+ u32 p, tmp;
+ s64 cn;
+
+ /*
+ * cnr[mdB] = 0.024 P^4 - 1.6 P^3 + 39.8 P^2 + 549.1 P + 3096.5
+ * (P = 10log10(5505024/cndat))
+ */
+ /* cn = cnr << 3 (61.3 fixed point float */
+ /* p = 10log10(5505024/cndat) << 24 (8.24 fixed point float)*/
+ p = intlog10(5505024) - intlog10(cndat);
+ p *= 10;
+
+ cn = 24772;
+ cn += div64_s64(43827LL * p, 10) >> 24;
+ tmp = p >> 8;
+ cn += div64_s64(3184LL * tmp * tmp, 10) >> 32;
+ tmp = p >> 13;
+ cn -= div64_s64(128LL * tmp * tmp * tmp, 10) >> 33;
+ tmp = p >> 18;
+ cn += div64_s64(192LL * tmp * tmp * tmp * tmp, 1000) >> 24;
+
+ stats->stat[0].svalue = cn >> 3;
+ stats->stat[0].scale = FE_SCALE_DECIBEL;
+ }
+
+ /* per-layer post viterbi BER (or PER? config dependent?) */
+ stats = &c->post_bit_error;
+ memset(stats, 0, sizeof(*stats));
+ stats->len = layers;
+ ret = reg_read(state, 0x9d, val, 15);
+ if (ret < 0)
+ for (i = 0; i < layers; i++)
+ stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ else {
+ for (i = 0; i < layers; i++) {
+ stats->stat[i].scale = FE_SCALE_COUNTER;
+ stats->stat[i].uvalue = val[i * 3] << 16
+ | val[i * 3 + 1] << 8 | val[i * 3 + 2];
+ }
+ }
+ stats = &c->post_bit_count;
+ memset(stats, 0, sizeof(*stats));
+ stats->len = layers;
+ if (ret < 0)
+ for (i = 0; i < layers; i++)
+ stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ else {
+ for (i = 0; i < layers; i++) {
+ stats->stat[i].scale = FE_SCALE_COUNTER;
+ stats->stat[i].uvalue =
+ val[9 + i * 2] << 8 | val[9 + i * 2 + 1];
+ stats->stat[i].uvalue *= 204 * 8;
+ }
+ }
+
+ return 0;
+}
+
+static const struct reg_val reset_sat = { 0x03, 0x01 };
+static const struct reg_val reset_ter = { 0x01, 0x40 };
+
+static int tc90522_set_frontend(struct dvb_frontend *fe)
+{
+ struct tc90522_state *state;
+ int ret;
+
+ state = fe->demodulator_priv;
+
+ if (fe->ops.tuner_ops.set_params)
+ ret = fe->ops.tuner_ops.set_params(fe);
+ else
+ ret = -ENODEV;
+ if (ret < 0)
+ goto failed;
+
+ if (fe->ops.delsys[0] == SYS_ISDBS) {
+ ret = tc90522s_set_tsid(fe);
+ if (ret < 0)
+ goto failed;
+ ret = reg_write(state, &reset_sat, 1);
+ } else {
+ ret = tc90522t_set_layers(fe);
+ if (ret < 0)
+ goto failed;
+ ret = reg_write(state, &reset_ter, 1);
+ }
+ if (ret < 0)
+ goto failed;
+
+ return 0;
+
+failed:
+ dev_warn(&state->tuner_i2c.dev, "(%s) failed. [adap%d-fe%d]\n",
+ __func__, fe->dvb->num, fe->id);
+ return ret;
+}
+
+static int tc90522_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *settings)
+{
+ if (fe->ops.delsys[0] == SYS_ISDBS) {
+ settings->min_delay_ms = 250;
+ settings->step_size = 1000;
+ settings->max_drift = settings->step_size * 2;
+ } else {
+ settings->min_delay_ms = 400;
+ settings->step_size = 142857;
+ settings->max_drift = settings->step_size;
+ }
+ return 0;
+}
+
+static int tc90522_set_if_agc(struct dvb_frontend *fe, bool on)
+{
+ struct reg_val agc_sat[] = {
+ { 0x0a, 0x00 },
+ { 0x10, 0x30 },
+ { 0x11, 0x00 },
+ { 0x03, 0x01 },
+ };
+ struct reg_val agc_ter[] = {
+ { 0x25, 0x00 },
+ { 0x23, 0x4c },
+ { 0x01, 0x40 },
+ };
+ struct tc90522_state *state;
+ struct reg_val *rv;
+ int num;
+
+ state = fe->demodulator_priv;
+ if (fe->ops.delsys[0] == SYS_ISDBS) {
+ agc_sat[0].val = on ? 0xff : 0x00;
+ agc_sat[1].val |= 0x80;
+ agc_sat[1].val |= on ? 0x01 : 0x00;
+ agc_sat[2].val |= on ? 0x40 : 0x00;
+ rv = agc_sat;
+ num = ARRAY_SIZE(agc_sat);
+ } else {
+ agc_ter[0].val = on ? 0x40 : 0x00;
+ agc_ter[1].val |= on ? 0x00 : 0x01;
+ rv = agc_ter;
+ num = ARRAY_SIZE(agc_ter);
+ }
+ return reg_write(state, rv, num);
+}
+
+static const struct reg_val sleep_sat = { 0x17, 0x01 };
+static const struct reg_val sleep_ter = { 0x03, 0x90 };
+
+static int tc90522_sleep(struct dvb_frontend *fe)
+{
+ struct tc90522_state *state;
+ int ret;
+
+ state = fe->demodulator_priv;
+ if (fe->ops.delsys[0] == SYS_ISDBS)
+ ret = reg_write(state, &sleep_sat, 1);
+ else {
+ ret = reg_write(state, &sleep_ter, 1);
+ if (ret == 0 && fe->ops.set_lna &&
+ fe->dtv_property_cache.lna == LNA_AUTO) {
+ fe->dtv_property_cache.lna = 0;
+ ret = fe->ops.set_lna(fe);
+ fe->dtv_property_cache.lna = LNA_AUTO;
+ }
+ }
+ if (ret < 0)
+ dev_warn(&state->tuner_i2c.dev,
+ "(%s) failed. [adap%d-fe%d]\n",
+ __func__, fe->dvb->num, fe->id);
+ return ret;
+}
+
+static const struct reg_val wakeup_sat = { 0x17, 0x00 };
+static const struct reg_val wakeup_ter = { 0x03, 0x80 };
+
+static int tc90522_init(struct dvb_frontend *fe)
+{
+ struct tc90522_state *state;
+ int ret;
+
+ /*
+ * Because the init sequence is not public,
+ * the parent device/driver should have init'ed the device before.
+ * just wake up the device here.
+ */
+
+ state = fe->demodulator_priv;
+ if (fe->ops.delsys[0] == SYS_ISDBS)
+ ret = reg_write(state, &wakeup_sat, 1);
+ else {
+ ret = reg_write(state, &wakeup_ter, 1);
+ if (ret == 0 && fe->ops.set_lna &&
+ fe->dtv_property_cache.lna == LNA_AUTO) {
+ fe->dtv_property_cache.lna = 1;
+ ret = fe->ops.set_lna(fe);
+ fe->dtv_property_cache.lna = LNA_AUTO;
+ }
+ }
+ if (ret < 0) {
+ dev_warn(&state->tuner_i2c.dev,
+ "(%s) failed. [adap%d-fe%d]\n",
+ __func__, fe->dvb->num, fe->id);
+ return ret;
+ }
+
+ /* prefer 'all-layers' to 'none' as a default */
+ if (fe->dtv_property_cache.isdbt_layer_enabled == 0)
+ fe->dtv_property_cache.isdbt_layer_enabled = 7;
+ return tc90522_set_if_agc(fe, true);
+}
+
+
+/*
+ * tuner I2C adapter functions
+ */
+
+static int
+tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct tc90522_state *state;
+ struct i2c_msg *new_msgs;
+ int i, j;
+ int ret, rd_num;
+ u8 wbuf[256];
+ u8 *p, *bufend;
+
+ if (num <= 0)
+ return -EINVAL;
+
+ rd_num = 0;
+ for (i = 0; i < num; i++)
+ if (msgs[i].flags & I2C_M_RD)
+ rd_num++;
+ new_msgs = kmalloc(sizeof(*new_msgs) * (num + rd_num), GFP_KERNEL);
+ if (!new_msgs)
+ return -ENOMEM;
+
+ state = i2c_get_adapdata(adap);
+ p = wbuf;
+ bufend = wbuf + sizeof(wbuf);
+ for (i = 0, j = 0; i < num; i++, j++) {
+ new_msgs[j].addr = state->i2c_client->addr;
+ new_msgs[j].flags = msgs[i].flags;
+
+ if (msgs[i].flags & I2C_M_RD) {
+ new_msgs[j].flags &= ~I2C_M_RD;
+ if (p + 2 > bufend)
+ break;
+ p[0] = TC90522_I2C_THRU_REG;
+ p[1] = msgs[i].addr << 1 | 0x01;
+ new_msgs[j].buf = p;
+ new_msgs[j].len = 2;
+ p += 2;
+ j++;
+ new_msgs[j].addr = state->i2c_client->addr;
+ new_msgs[j].flags = msgs[i].flags;
+ new_msgs[j].buf = msgs[i].buf;
+ new_msgs[j].len = msgs[i].len;
+ continue;
+ }
+
+ if (p + msgs[i].len + 2 > bufend)
+ break;
+ p[0] = TC90522_I2C_THRU_REG;
+ p[1] = msgs[i].addr << 1;
+ memcpy(p + 2, msgs[i].buf, msgs[i].len);
+ new_msgs[j].buf = p;
+ new_msgs[j].len = msgs[i].len + 2;
+ p += new_msgs[j].len;
+ }
+
+ if (i < num)
+ ret = -ENOMEM;
+ else
+ ret = i2c_transfer(state->i2c_client->adapter, new_msgs, j);
+ if (ret >= 0 && ret < j)
+ ret = -EIO;
+ kfree(new_msgs);
+ return (ret == j) ? num : ret;
+}
+
+static u32 tc90522_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm tc90522_tuner_i2c_algo = {
+ .master_xfer = &tc90522_master_xfer,
+ .functionality = &tc90522_functionality,
+};
+
+
+/*
+ * I2C driver functions
+ */
+
+static const struct dvb_frontend_ops tc90522_ops_sat = {
+ .delsys = { SYS_ISDBS },
+ .info = {
+ .name = "Toshiba TC90522 ISDB-S module",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .init = tc90522_init,
+ .sleep = tc90522_sleep,
+ .set_frontend = tc90522_set_frontend,
+ .get_tune_settings = tc90522_get_tune_settings,
+
+ .get_frontend = tc90522s_get_frontend,
+ .read_status = tc90522s_read_status,
+};
+
+static const struct dvb_frontend_ops tc90522_ops_ter = {
+ .delsys = { SYS_ISDBT },
+ .info = {
+ .name = "Toshiba TC90522 ISDB-T module",
+ .frequency_min = 470000000,
+ .frequency_max = 770000000,
+ .frequency_stepsize = 142857,
+ .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,
+ },
+
+ .init = tc90522_init,
+ .sleep = tc90522_sleep,
+ .set_frontend = tc90522_set_frontend,
+ .get_tune_settings = tc90522_get_tune_settings,
+
+ .get_frontend = tc90522t_get_frontend,
+ .read_status = tc90522t_read_status,
+};
+
+
+static int tc90522_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct tc90522_state *state;
+ struct tc90522_config *cfg;
+ const struct dvb_frontend_ops *ops;
+ struct i2c_adapter *adap;
+ int ret;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+ state->i2c_client = client;
+
+ cfg = client->dev.platform_data;
+ memcpy(&state->cfg, cfg, sizeof(state->cfg));
+ cfg->fe = state->cfg.fe = &state->fe;
+ ops = id->driver_data == 0 ? &tc90522_ops_sat : &tc90522_ops_ter;
+ memcpy(&state->fe.ops, ops, sizeof(*ops));
+ state->fe.demodulator_priv = state;
+
+ adap = &state->tuner_i2c;
+ adap->owner = THIS_MODULE;
+ adap->algo = &tc90522_tuner_i2c_algo;
+ adap->dev.parent = &client->dev;
+ strlcpy(adap->name, "tc90522_sub", sizeof(adap->name));
+ i2c_set_adapdata(adap, state);
+ ret = i2c_add_adapter(adap);
+ if (ret < 0)
+ goto err;
+ cfg->tuner_i2c = state->cfg.tuner_i2c = adap;
+
+ i2c_set_clientdata(client, &state->cfg);
+ dev_info(&client->dev, "Toshiba TC90522 attached.\n");
+ return 0;
+
+err:
+ kfree(state);
+ return ret;
+}
+
+static int tc90522_remove(struct i2c_client *client)
+{
+ struct tc90522_state *state;
+
+ state = cfg_to_state(i2c_get_clientdata(client));
+ i2c_del_adapter(&state->tuner_i2c);
+ kfree(state);
+ return 0;
+}
+
+
+static const struct i2c_device_id tc90522_id[] = {
+ { TC90522_I2C_DEV_SAT, 0 },
+ { TC90522_I2C_DEV_TER, 1 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, tc90522_id);
+
+static struct i2c_driver tc90522_driver = {
+ .driver = {
+ .name = "tc90522",
+ },
+ .probe = tc90522_probe,
+ .remove = tc90522_remove,
+ .id_table = tc90522_id,
+};
+
+module_i2c_driver(tc90522_driver);
+
+MODULE_DESCRIPTION("Toshiba TC90522 frontend");
+MODULE_AUTHOR("Akihiro TSUKADA");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tc90522.h b/drivers/media/dvb-frontends/tc90522.h
new file mode 100644
index 0000000..b1cbddf
--- /dev/null
+++ b/drivers/media/dvb-frontends/tc90522.h
@@ -0,0 +1,42 @@
+/*
+ * Toshiba TC90522 Demodulator
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@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.
+ */
+
+/*
+ * The demod has 4 input (2xISDB-T and 2xISDB-S),
+ * and provides independent sub modules for each input.
+ * As the sub modules work in parallel and have the separate i2c addr's,
+ * this driver treats each sub module as one demod device.
+ */
+
+#ifndef TC90522_H
+#define TC90522_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* I2C device types */
+#define TC90522_I2C_DEV_SAT "tc90522sat"
+#define TC90522_I2C_DEV_TER "tc90522ter"
+
+struct tc90522_config {
+ /* [OUT] frontend returned by driver */
+ struct dvb_frontend *fe;
+
+ /* [OUT] tuner I2C adapter returned by driver */
+ struct i2c_adapter *tuner_i2c;
+};
+
+#endif /* TC90522_H */
diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
index 9619be5..4a19b85 100644
--- a/drivers/media/dvb-frontends/tda10071.c
+++ b/drivers/media/dvb-frontends/tda10071.c
@@ -1037,7 +1037,7 @@ static int tda10071_init(struct dvb_frontend *fe)
ret = -EFAULT;
goto error;
} else {
- priv->warm = 1;
+ priv->warm = true;
}
cmd.args[0] = CMD_GET_FW_VERSION;
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index 91b6b2e..ee09ec2 100644
--- a/drivers/media/dvb-frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
@@ -111,7 +111,7 @@ static int zl10039_write(struct zl10039_state *state,
if (1 + count > sizeof(buf)) {
printk(KERN_WARNING
- "%s: i2c wr reg=%04x: len=%zd is too big!\n",
+ "%s: i2c wr reg=%04x: len=%zu is too big!\n",
KBUILD_MODNAME, reg, count);
return -EINVAL;
}
diff --git a/drivers/media/firewire/firedtv-avc.c b/drivers/media/firewire/firedtv-avc.c
index d1a1a13..251a556 100644
--- a/drivers/media/firewire/firedtv-avc.c
+++ b/drivers/media/firewire/firedtv-avc.c
@@ -1157,6 +1157,10 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
dev_err(fdtv->device,
"invalid pmt_cmd_id %d\n", pmt_cmd_id);
+ if (program_info_length > sizeof(c->operand) - 4 - write_pos) {
+ ret = -EINVAL;
+ goto out;
+ }
memcpy(&c->operand[write_pos], &msg[read_pos],
program_info_length);
@@ -1180,6 +1184,12 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
dev_err(fdtv->device, "invalid pmt_cmd_id %d "
"at stream level\n", pmt_cmd_id);
+ if (es_info_length > sizeof(c->operand) - 4 -
+ write_pos) {
+ ret = -EINVAL;
+ goto out;
+ }
+
memcpy(&c->operand[write_pos], &msg[read_pos],
es_info_length);
read_pos += es_info_length;
diff --git a/drivers/media/i2c/adv7343_regs.h b/drivers/media/i2c/adv7343_regs.h
index 4466067..2f04ce4 100644
--- a/drivers/media/i2c/adv7343_regs.h
+++ b/drivers/media/i2c/adv7343_regs.h
@@ -13,7 +13,7 @@
* GNU General Public License for more details.
*/
-#ifndef ADV7343_REG_H
+#ifndef ADV7343_REGS_H
#define ADV7343_REGS_H
struct adv7343_std_info {
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index de88b98..47795ff 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1593,7 +1593,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
bt->height += hdmi_read16(sd, 0x0b, 0xfff);
bt->il_vfrontporch = hdmi_read16(sd, 0x2c, 0x1fff) / 2;
bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2;
- bt->vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
+ bt->il_vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
}
adv7604_fill_optional_dv_timings_fields(sd, timings);
} else {
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 0d55491..48b628b 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -1435,6 +1435,8 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+ memset(timings, 0, sizeof(struct v4l2_dv_timings));
+
/* SDP block */
if (state->mode == ADV7842_MODE_SDP)
return -ENODATA;
@@ -1483,7 +1485,7 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
hdmi_read(sd, 0x2d)) / 2;
bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x1f) * 256 +
hdmi_read(sd, 0x31)) / 2;
- bt->vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
+ bt->il_vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
hdmi_read(sd, 0x35)) / 2;
}
adv7842_fill_optional_dv_timings_fields(sd, timings);
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index e6588ee..4cf8f18 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -224,7 +224,7 @@ static inline unsigned int lpf_count_to_us(unsigned int count)
}
/*
- * FIFO register pulse width count compuations
+ * FIFO register pulse width count computations
*/
static u32 clock_divider_to_resolution(u16 divider)
{
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index c23de59..d9ece4b 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -100,14 +100,14 @@ static int lm3560_enable_ctrl(struct lm3560_flash *flash,
int rval;
if (led_no == LM3560_LED0) {
- if (on == true)
+ if (on)
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x08, 0x08);
else
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x08, 0x00);
} else {
- if (on == true)
+ if (on)
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x10, 0x10);
else
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index cdd7c1b..dd3db24 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -19,6 +19,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-mediabus.h>
+#include <media/v4l2-image-sizes.h>
#include <media/ov7670.h>
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
@@ -30,19 +31,6 @@ 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
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 564f05f..0e461a6 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -816,7 +816,7 @@ static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
"error setting frame interval: %d\n", err);
state->error = -EINVAL;
}
- };
+ }
v4l2_err(&state->sd, "cannot find correct frame interval\n");
state->error = -ERANGE;
}
diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c
index 04e9e55..4024ea6 100644
--- a/drivers/media/i2c/saa6752hs.c
+++ b/drivers/media/i2c/saa6752hs.c
@@ -660,7 +660,7 @@ static const struct v4l2_subdev_ops saa6752hs_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 saa6752hs_state *h;
struct v4l2_subdev *sd;
struct v4l2_ctrl_handler *hdl;
u8 addr = 0x13;
@@ -668,6 +668,8 @@ static int saa6752hs_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
+
+ h = devm_kzalloc(&client->dev, sizeof(*h), GFP_KERNEL);
if (h == NULL)
return -ENOMEM;
sd = &h->sd;
@@ -752,7 +754,6 @@ static int saa6752hs_probe(struct i2c_client *client,
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(h);
return err;
}
v4l2_ctrl_cluster(3, &h->video_bitrate_mode);
@@ -767,7 +768,6 @@ static int saa6752hs_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&to_state(sd)->hdl);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 62acb10..932ed9b 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -31,8 +31,9 @@
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/smiapp.h>
#include <linux/v4l2-mediabus.h>
#include <media/v4l2-device.h>
@@ -297,8 +298,9 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
if (rval < 0)
return rval;
- *sensor->pixel_rate_parray->p_cur.p_s64 = pll->vt_pix_clk_freq_hz;
- *sensor->pixel_rate_csi->p_cur.p_s64 = pll->pixel_rate_csi;
+ __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray,
+ pll->vt_pix_clk_freq_hz);
+ __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi);
return 0;
}
@@ -319,13 +321,7 @@ static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
+ 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;
+ __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max);
}
/*
@@ -404,6 +400,14 @@ static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor)
pixel_order_str[pixel_order]);
}
+static const char * const smiapp_test_patterns[] = {
+ "Disabled",
+ "Solid Colour",
+ "Eight Vertical Colour Bars",
+ "Colour Bars With Fade to Grey",
+ "Pseudorandom Sequence (PN9)",
+};
+
static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct smiapp_sensor *sensor =
@@ -477,6 +481,39 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
return smiapp_pll_update(sensor);
+ case V4L2_CID_TEST_PATTERN: {
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
+ v4l2_ctrl_activate(
+ sensor->test_data[i],
+ ctrl->val ==
+ V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
+
+ return smiapp_write(
+ sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
+ }
+
+ case V4L2_CID_TEST_PATTERN_RED:
+ return smiapp_write(
+ sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
+
+ case V4L2_CID_TEST_PATTERN_GREENR:
+ return smiapp_write(
+ sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
+
+ case V4L2_CID_TEST_PATTERN_BLUE:
+ return smiapp_write(
+ sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
+
+ case V4L2_CID_TEST_PATTERN_GREENB:
+ return smiapp_write(
+ sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
+
+ case V4L2_CID_PIXEL_RATE:
+ /* For v4l2_ctrl_s_ctrl_int64() used internally. */
+ return 0;
+
default:
return -EINVAL;
}
@@ -489,10 +526,10 @@ static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
static int smiapp_init_controls(struct smiapp_sensor *sensor)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int max;
+ unsigned int max, i;
int rval;
- rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 7);
+ rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 12);
if (rval)
return rval;
sensor->pixel_array->ctrl_handler.lock = &sensor->mutex;
@@ -535,6 +572,20 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
&sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
+ v4l2_ctrl_new_std_menu_items(&sensor->pixel_array->ctrl_handler,
+ &smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(smiapp_test_patterns) - 1,
+ 0, 0, smiapp_test_patterns);
+
+ for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) {
+ int max_value = (1 << sensor->csi_format->width) - 1;
+ sensor->test_data[i] =
+ v4l2_ctrl_new_std(
+ &sensor->pixel_array->ctrl_handler,
+ &smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN_RED + i,
+ 0, max_value, 1, max_value);
+ }
+
if (sensor->pixel_array->ctrl_handler.error) {
dev_err(&client->dev,
"pixel array controls initialization failed (%d)\n",
@@ -782,36 +833,25 @@ static void smiapp_update_blanking(struct smiapp_sensor *sensor)
{
struct v4l2_ctrl *vblank = sensor->vblank;
struct v4l2_ctrl *hblank = sensor->hblank;
+ int min, max;
- 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] -
+ min = 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);
+ max = 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] -
+ __v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min);
+
+ min = 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]);
+ max = 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;
+ __v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min);
__smiapp_update_exposure_limits(sensor);
}
@@ -1272,7 +1312,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor)
clk_disable_unprepare(sensor->ext_clk);
usleep_range(5000, 5000);
regulator_disable(sensor->vana);
- sensor->streaming = 0;
+ sensor->streaming = false;
}
static int smiapp_set_power(struct v4l2_subdev *subdev, int on)
@@ -1462,13 +1502,13 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
return 0;
if (enable) {
- sensor->streaming = 1;
+ sensor->streaming = true;
rval = smiapp_start_streaming(sensor);
if (rval < 0)
- sensor->streaming = 0;
+ sensor->streaming = false;
} else {
rval = smiapp_stop_streaming(sensor);
- sensor->streaming = 0;
+ sensor->streaming = false;
}
return rval;
@@ -1664,17 +1704,34 @@ static int smiapp_set_format(struct v4l2_subdev *subdev,
if (fmt->pad == ssd->source_pad) {
u32 code = fmt->format.code;
int rval = __smiapp_get_format(subdev, fh, fmt);
+ bool range_changed = false;
+ unsigned int i;
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)
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+ if (csi_format->width !=
+ sensor->csi_format->width)
+ range_changed = true;
+
sensor->csi_format = csi_format;
+ }
+
fmt->format.code = csi_format->code;
}
mutex_unlock(&sensor->mutex);
- return rval;
+ if (rval || !range_changed)
+ return rval;
+
+ for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
+ v4l2_ctrl_modify_range(
+ sensor->test_data[i],
+ 0, (1 << sensor->csi_format->width) - 1, 1, 0);
+
+ return 0;
}
/* Sink pad. Width and height are changeable here. */
diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h
index 7cc5aae..874b49f 100644
--- a/drivers/media/i2c/smiapp/smiapp.h
+++ b/drivers/media/i2c/smiapp/smiapp.h
@@ -54,6 +54,8 @@
(1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \
+ (clk) / 1000 - 1) / ((clk) / 1000))
+#define SMIAPP_COLOUR_COMPONENTS 4
+
#include "smiapp-limits.h"
struct smiapp_quirk;
@@ -241,6 +243,8 @@ struct smiapp_sensor {
/* src controls */
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *pixel_rate_csi;
+ /* test pattern colour components */
+ struct v4l2_ctrl *test_data[SMIAPP_COLOUR_COMPONENTS];
};
#define to_smiapp_subdev(_sd) \
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index 46f431a..996d7b4 100644
--- a/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -29,6 +29,7 @@
#include <media/soc_camera.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-image-sizes.h>
/* you can check PLL/clock info */
/* #define EXT_CLOCK 24000000 */
@@ -42,9 +43,6 @@
#define MAX_WIDTH 2048
#define MAX_HEIGHT 1536
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-
/*
* macro of read/write
*/
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index 7f2b3c8..970a04e 100644
--- a/drivers/media/i2c/soc_camera/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -29,6 +29,7 @@
#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
+#include <media/v4l2-image-sizes.h>
/*
* register offset
@@ -360,10 +361,6 @@
#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-#define QVGA_WIDTH 320
-#define QVGA_HEIGHT 240
#define OV772X_MAX_WIDTH VGA_WIDTH
#define OV772X_MAX_HEIGHT VGA_HEIGHT
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index ea76863..ee9eb63 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -564,13 +564,13 @@ static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
u32 y_start;
u32 x_end;
u32 y_end;
- bool scaling = 0;
+ bool scaling = false;
u32 scale_input_x;
u32 scale_input_y;
int ret;
if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
- scaling = 1;
+ scaling = true;
/*
* Try to use as much of the sensor area as possible when supporting
diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c
index 72af644..cf93021 100644
--- a/drivers/media/i2c/tda7432.c
+++ b/drivers/media/i2c/tda7432.c
@@ -293,7 +293,7 @@ static int tda7432_s_ctrl(struct v4l2_ctrl *ctrl)
if (t->mute->val) {
lf |= TDA7432_MUTE;
lr |= TDA7432_MUTE;
- lf |= TDA7432_MUTE;
+ rf |= TDA7432_MUTE;
rr |= TDA7432_MUTE;
}
/* Mute & update balance*/
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 11f2387..51bac76 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -775,25 +775,20 @@ static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
{
struct tvp7002 *device = to_tvp7002(sd);
- int error = 0;
+ int error;
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;
+ /* low impedance: on, high impedance: off */
+ error = tvp7002_write(sd, TVP7002_MISC_CTL_2, enable ? 0x00 : 0x03);
+ if (error) {
+ v4l2_dbg(1, debug, sd, "Fail to set streaming\n");
+ return error;
}
- return error;
+ device->streaming = enable;
+ return 0;
}
/*
diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
index 23f4f65..373f2df 100644
--- a/drivers/media/i2c/vs6624.c
+++ b/drivers/media/i2c/vs6624.c
@@ -30,22 +30,10 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
+#include <media/v4l2-image-sizes.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 {
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 73a4329..7b39440 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -103,10 +103,8 @@ static long media_device_enum_entities(struct media_device *mdev,
return -EINVAL;
u_ent.id = ent->id;
- if (ent->name) {
- strncpy(u_ent.name, ent->name, sizeof(u_ent.name));
- u_ent.name[sizeof(u_ent.name) - 1] = '\0';
- }
+ if (ent->name)
+ strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
u_ent.type = ent->type;
u_ent.revision = ent->revision;
u_ent.flags = ent->flags;
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
index 7acd19c..ebf9626 100644
--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -192,7 +192,6 @@ static int media_open(struct inode *inode, struct file *filp)
static int media_release(struct inode *inode, struct file *filp)
{
struct media_devnode *mdev = media_devnode_data(filp);
- int ret = 0;
if (mdev->fops->release)
mdev->fops->release(filp);
@@ -201,7 +200,7 @@ static int media_release(struct inode *inode, struct file *filp)
return value is ignored. */
put_device(&mdev->dev);
filp->private_data = NULL;
- return ret;
+ return 0;
}
static const struct file_operations media_devnode_fops = {
diff --git a/drivers/media/parport/pms.c b/drivers/media/parport/pms.c
index 9bc105b..e6b4975 100644
--- a/drivers/media/parport/pms.c
+++ b/drivers/media/parport/pms.c
@@ -629,11 +629,15 @@ 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 */
+ char *tmp; /* using a temp buffer is faster than direct */
int cnt = 0;
int len = 0;
unsigned char r8 = 0x5; /* value for reg8 */
+ tmp = kmalloc(dw + 32, GFP_KERNEL);
+ if (!tmp)
+ return 0;
+
if (rgb555)
r8 |= 0x20; /* else use untranslated rgb = 565 */
mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
@@ -664,6 +668,7 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
len += dt;
}
}
+ kfree(tmp);
return len;
}
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index 5c16c9c..f8cec8e 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -20,6 +20,7 @@ source "drivers/media/pci/ivtv/Kconfig"
source "drivers/media/pci/zoran/Kconfig"
source "drivers/media/pci/saa7146/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
+source "drivers/media/pci/tw68/Kconfig"
endif
if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
@@ -41,6 +42,7 @@ source "drivers/media/pci/b2c2/Kconfig"
source "drivers/media/pci/pluto2/Kconfig"
source "drivers/media/pci/dm1105/Kconfig"
source "drivers/media/pci/pt1/Kconfig"
+source "drivers/media/pci/pt3/Kconfig"
source "drivers/media/pci/mantis/Kconfig"
source "drivers/media/pci/ngene/Kconfig"
source "drivers/media/pci/ddbridge/Kconfig"
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index e5b53fb..a12926e 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -7,10 +7,10 @@ obj-y += ttpci/ \
pluto2/ \
dm1105/ \
pt1/ \
+ pt3/ \
mantis/ \
ngene/ \
ddbridge/ \
- b2c2/ \
saa7146/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
@@ -22,6 +22,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
+obj-$(CONFIG_VIDEO_TW68) += tw68/
obj-$(CONFIG_VIDEO_MEYE) += meye/
obj-$(CONFIG_STA2X11_VIP) += sta2x11/
obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 970e542..4a8176c 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -1531,7 +1531,6 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
{
struct bttv_buffer *old;
unsigned long flags;
- int retval = 0;
dprintk("switch_overlay: enter [new=%p]\n", new);
if (new)
@@ -1551,7 +1550,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
if (NULL == new)
free_btres_lock(btv,fh,RESOURCE_OVERLAY);
dprintk("switch_overlay: done\n");
- return retval;
+ return 0;
}
/* ----------------------------------------------------------------------- */
@@ -3856,7 +3855,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
BT848_INT_MASK);
- };
+ }
bttv_print_irqbits(stat,astat);
diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
index 0e788fc..c22c4ae 100644
--- a/drivers/media/pci/bt8xx/dst_ca.c
+++ b/drivers/media/pci/bt8xx/dst_ca.c
@@ -674,11 +674,9 @@ static int dst_ca_release(struct inode *inode, struct file *file)
static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
- ssize_t bytes_read = 0;
-
dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
- return bytes_read;
+ return 0;
}
static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c
index 180077c..ffb6acd 100644
--- a/drivers/media/pci/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c
@@ -80,7 +80,7 @@ void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
int period_elapsed = 0;
int length;
- dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
+ dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zu\n", cxsc,
pcm_data, num_bytes);
substream = cxsc->capture_pcm_substream;
diff --git a/drivers/media/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
index a1c1cec..c6c8344 100644
--- a/drivers/media/pci/cx18/cx18-firmware.c
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -130,7 +130,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
}
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
- CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
+ CX18_INFO("loaded %s firmware (%zu bytes)\n", fn, fw->size);
size = fw->size;
release_firmware(fw);
cx18_setup_page(cx, SCB_OFFSET);
@@ -164,7 +164,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
while (offset + sizeof(seghdr) < fw->size) {
- const u32 *shptr = src + offset / 4;
+ const __le32 *shptr = (__force __le32 *)src + offset / 4;
seghdr.sync1 = le32_to_cpu(shptr[0]);
seghdr.sync2 = le32_to_cpu(shptr[1]);
@@ -202,7 +202,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
offset += seghdr.size;
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
- CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
+ CX18_INFO("loaded %s firmware V%08x (%zu bytes)\n",
fn, apu_version, fw->size);
size = fw->size;
release_firmware(fw);
diff --git a/drivers/media/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c
index 8884537..2a247d2 100644
--- a/drivers/media/pci/cx18/cx18-queue.c
+++ b/drivers/media/pci/cx18/cx18-queue.c
@@ -364,7 +364,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
((char __iomem *)cx->scb->cpu_mdl));
CX18_ERR("Too many buffers, cannot fit in SCB area\n");
- CX18_ERR("Max buffers = %zd\n",
+ CX18_ERR("Max buffers = %zu\n",
bufsz / sizeof(struct cx18_mdl_ent));
return -ENOMEM;
}
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
index e12c006..f613314 100644
--- a/drivers/media/pci/cx23885/Kconfig
+++ b/drivers/media/pci/cx23885/Kconfig
@@ -3,12 +3,11 @@ config VIDEO_CX23885
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 VIDEOBUF2_DVB
+ select VIDEOBUF2_DMA_SG
select VIDEO_CX25840
select VIDEO_CX2341X
select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
@@ -32,12 +31,16 @@ config VIDEO_CX23885
select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Conexant 23885 based
diff --git a/drivers/media/pci/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index 2a2cafb..a2cbdcf 100644
--- a/drivers/media/pci/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
ccflags-y += -Idrivers/media/i2c
-ccflags-y += -Idrivers/media/common
ccflags-y += -Idrivers/media/tuners
ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
index 2926f7f..2bbbf54 100644
--- a/drivers/media/pci/cx23885/altera-ci.c
+++ b/drivers/media/pci/cx23885/altera-ci.c
@@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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.
*/
/*
@@ -52,8 +48,8 @@
* | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
#include "altera-ci.h"
#include "dvb_ca_en50221.h"
diff --git a/drivers/media/pci/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h
index 4998c96..5028f0c 100644
--- a/drivers/media/pci/cx23885/altera-ci.h
+++ b/drivers/media/pci/cx23885/altera-ci.h
@@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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
diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c
index 16fa7ea..631e4f2 100644
--- a/drivers/media/pci/cx23885/cimax2.c
+++ b/drivers/media/pci/cx23885/cimax2.c
@@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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"
diff --git a/drivers/media/pci/cx23885/cimax2.h b/drivers/media/pci/cx23885/cimax2.h
index 518744a..565e958 100644
--- a/drivers/media/pci/cx23885/cimax2.h
+++ b/drivers/media/pci/cx23885/cimax2.h
@@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index bf89fc8..3948db3 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -18,10 +18,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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>
@@ -865,6 +861,11 @@ static int cx23885_api_cmd(struct cx23885_dev *dev,
return err;
}
+static int cx23885_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
+{
+ return cx23885_mbox_func(priv, cmd, in, out, data);
+}
+
static int cx23885_find_mailbox(struct cx23885_dev *dev)
{
u32 signature[4] = {
@@ -941,7 +942,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
if (firmware->size != CX23885_FIRM_IMAGE_SIZE) {
printk(KERN_ERR "ERROR: Firmware size mismatch "
- "(have %zd, expected %d)\n",
+ "(have %zu, expected %d)\n",
firmware->size, CX23885_FIRM_IMAGE_SIZE);
release_firmware(firmware);
return -1;
@@ -1033,12 +1034,12 @@ static void cx23885_codec_settings(struct cx23885_dev *dev)
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->cxhdl.width = dev->ts1.width;
+ dev->cxhdl.height = dev->ts1.height;
+ dev->cxhdl.is_50hz =
(dev->encodernorm.id & V4L2_STD_625_50) != 0;
- cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params);
+ cx2341x_handler_setup(&dev->cxhdl);
cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
@@ -1137,85 +1138,107 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
/* ------------------------------------------------------------------ */
-static int bb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], void *alloc_ctxs[])
{
- 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;
+ struct cx23885_dev *dev = q->drv_priv;
+ dev->ts1.ts_packet_size = mpeglinesize;
+ dev->ts1.ts_packet_count = mpeglines;
+ *num_planes = 1;
+ sizes[0] = mpeglinesize * mpeglines;
+ *num_buffers = mpegbufs;
return 0;
}
-static int bb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb)
{
- struct cx23885_fh *fh = q->priv_data;
- return cx23885_buf_prepare(q, &fh->dev->ts1,
- (struct cx23885_buffer *)vb,
- field);
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf =
+ container_of(vb, struct cx23885_buffer, vb);
+
+ return cx23885_buf_prepare(buf, &dev->ts1);
}
-static void bb_buf_queue(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
{
- struct cx23885_fh *fh = q->priv_data;
- cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb);
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer, vb);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+ cx23885_free_buffer(dev, buf);
+
+ dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
}
-static void bb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
+static void buffer_queue(struct vb2_buffer *vb)
{
- cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
-}
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf = container_of(vb,
+ 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,
-};
+ cx23885_buf_queue(&dev->ts1, buf);
+}
-/* ------------------------------------------------------------------ */
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct cx23885_dev *dev = q->drv_priv;
+ struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq;
+ unsigned long flags;
+ int ret;
+
+ ret = cx23885_initialize_codec(dev, 1);
+ if (ret == 0) {
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
+
+ cx23885_start_dma(&dev->ts1, dmaq, buf);
+ return 0;
+ }
+ spin_lock_irqsave(&dev->slock, flags);
+ while (!list_empty(&dmaq->active)) {
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
-static const u32 *ctrl_classes[] = {
- cx2341x_mpeg_ctrls,
- NULL
-};
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ }
+ spin_unlock_irqrestore(&dev->slock, flags);
+ return ret;
+}
-static int cx23885_queryctrl(struct cx23885_dev *dev,
- struct v4l2_queryctrl *qctrl)
+static void cx23885_stop_streaming(struct vb2_queue *q)
{
- qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
- if (qctrl->id == 0)
- return -EINVAL;
+ struct cx23885_dev *dev = q->drv_priv;
- /* MPEG V4L2 controls */
- if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
- qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ /* stop mpeg capture */
+ cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+ CX23885_END_NOW, CX23885_MPEG_CAPTURE,
+ CX23885_RAW_BITS_NONE);
- return 0;
+ msleep(500);
+ cx23885_417_check_encoder(dev);
+ cx23885_cancel_buffers(&dev->ts1);
}
-static int cx23885_querymenu(struct cx23885_dev *dev,
- struct v4l2_querymenu *qmenu)
-{
- struct v4l2_queryctrl qctrl;
+static struct vb2_ops cx23885_qops = {
+ .queue_setup = queue_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_finish = buffer_finish,
+ .buf_queue = buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = cx23885_start_streaming,
+ .stop_streaming = cx23885_stop_streaming,
+};
- 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;
+ struct cx23885_dev *dev = video_drvdata(file);
*id = dev->tvnorm;
return 0;
@@ -1223,29 +1246,26 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
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;
+ struct cx23885_dev *dev = video_drvdata(file);
unsigned int i;
+ int ret;
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;
+ ret = cx23885_set_tvnorm(dev, id);
+ if (!ret)
+ dev->encodernorm = cx23885_tvnorms[i];
+ return ret;
}
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
dprintk(1, "%s()\n", __func__);
return cx23885_enum_input(dev, i);
}
@@ -1263,8 +1283,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int 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;
+ struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@@ -1281,8 +1300,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *t)
{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@@ -1296,8 +1314,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
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;
+ struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@@ -1315,27 +1332,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
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_dev *dev = video_drvdata(file);
struct cx23885_tsport *tsport = &dev->ts1;
strlcpy(cap->driver, dev->name, sizeof(cap->driver));
@@ -1368,8 +1368,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
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;
+ struct cx23885_dev *dev = video_drvdata(file);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
@@ -1378,285 +1377,63 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
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);
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
+ dev->ts1.width, dev->ts1.height);
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;
+ struct cx23885_dev *dev = video_drvdata(file);
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);
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
+ dev->ts1.width, dev->ts1.height);
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;
+ struct cx23885_dev *dev = video_drvdata(file);
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.field = V4L2_FIELD_INTERLACED;
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;
+ struct cx23885_dev *dev = video_drvdata(file);
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);
+ v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, 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,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
};
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
@@ -1669,25 +1446,19 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.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_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .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 = vidioc_log_status,
- .vidioc_querymenu = vidioc_querymenu,
- .vidioc_queryctrl = vidioc_queryctrl,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_chip_info = cx23885_g_chip_info,
.vidioc_g_register = cx23885_g_register,
@@ -1711,6 +1482,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev)
video_unregister_device(dev->v4l_device);
else
video_device_release(dev->v4l_device);
+ v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
dev->v4l_device = NULL;
}
}
@@ -1742,6 +1514,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
/* FIXME: Port1 hardcoded here */
int err = -ENODEV;
struct cx23885_tsport *tsport = &dev->ts1;
+ struct vb2_queue *q;
dprintk(1, "%s()\n", __func__);
@@ -1757,14 +1530,36 @@ int cx23885_417_register(struct cx23885_dev *dev)
tsport->height = 576;
tsport->width = 720;
- cx2341x_fill_defaults(&dev->mpeg_params);
-
- dev->mpeg_params.port = CX2341X_PORT_SERIAL;
+ dev->cxhdl.port = CX2341X_PORT_SERIAL;
+ err = cx2341x_handler_init(&dev->cxhdl, 50);
+ if (err)
+ return err;
+ dev->cxhdl.priv = dev;
+ dev->cxhdl.func = cx23885_api_func;
+ cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
+ v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL);
/* Allocate and initialize V4L video device */
dev->v4l_device = cx23885_video_dev_alloc(tsport,
dev->pci, &cx23885_mpeg_template, "mpeg");
+ q = &dev->vb2_mpegq;
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+ q->gfp_flags = GFP_DMA32;
+ q->min_buffers_needed = 2;
+ q->drv_priv = dev;
+ q->buf_struct_size = sizeof(struct cx23885_buffer);
+ q->ops = &cx23885_qops;
+ q->mem_ops = &vb2_dma_sg_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &dev->lock;
+
+ err = vb2_queue_init(q);
+ if (err < 0)
+ return err;
video_set_drvdata(dev->v4l_device, dev);
+ dev->v4l_device->lock = &dev->lock;
+ dev->v4l_device->queue = q;
err = video_register_device(dev->v4l_device,
VFL_TYPE_GRABBER, -1);
if (err < 0) {
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index 554798d..ae7c2e8 100644
--- a/drivers/media/pci/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
@@ -15,10 +15,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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>
@@ -84,6 +80,82 @@ MODULE_PARM_DESC(audio_debug, "enable debug messages [analog audio]");
#define AUD_INT_MCHG_IRQ (1 << 21)
#define GP_COUNT_CONTROL_RESET 0x3
+static int cx23885_alsa_dma_init(struct cx23885_audio_dev *chip, int nr_pages)
+{
+ struct cx23885_audio_buffer *buf = chip->buf;
+ struct page *pg;
+ int i;
+
+ buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+ if (NULL == buf->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)buf->vaddr,
+ nr_pages << PAGE_SHIFT);
+
+ memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
+ buf->nr_pages = nr_pages;
+
+ buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist));
+ if (NULL == buf->sglist)
+ goto vzalloc_err;
+
+ sg_init_table(buf->sglist, buf->nr_pages);
+ for (i = 0; i < buf->nr_pages; i++) {
+ pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE);
+ if (NULL == pg)
+ goto vmalloc_to_page_err;
+ sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0);
+ }
+ return 0;
+
+vmalloc_to_page_err:
+ vfree(buf->sglist);
+ buf->sglist = NULL;
+vzalloc_err:
+ vfree(buf->vaddr);
+ buf->vaddr = NULL;
+ return -ENOMEM;
+}
+
+static int cx23885_alsa_dma_map(struct cx23885_audio_dev *dev)
+{
+ struct cx23885_audio_buffer *buf = dev->buf;
+
+ buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist,
+ buf->nr_pages, PCI_DMA_FROMDEVICE);
+
+ if (0 == buf->sglen) {
+ pr_warn("%s: cx23885_alsa_map_sg failed\n", __func__);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int cx23885_alsa_dma_unmap(struct cx23885_audio_dev *dev)
+{
+ struct cx23885_audio_buffer *buf = dev->buf;
+
+ if (!buf->sglen)
+ return 0;
+
+ dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE);
+ buf->sglen = 0;
+ return 0;
+}
+
+static int cx23885_alsa_dma_free(struct cx23885_audio_buffer *buf)
+{
+ vfree(buf->sglist);
+ buf->sglist = NULL;
+ vfree(buf->vaddr);
+ buf->vaddr = NULL;
+ return 0;
+}
+
/*
* BOARD Specific: Sets audio DMA
*/
@@ -198,15 +270,18 @@ int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask)
static int dsp_buffer_free(struct cx23885_audio_dev *chip)
{
+ struct cx23885_riscmem *risc;
+
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);
+ cx23885_alsa_dma_unmap(chip);
+ cx23885_alsa_dma_free(chip->buf);
+ risc = &chip->buf->risc;
+ pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma);
kfree(chip->buf);
- chip->dma_risc = NULL;
+ chip->buf = NULL;
chip->dma_size = 0;
return 0;
@@ -289,6 +364,7 @@ static int snd_cx23885_close(struct snd_pcm_substream *substream)
return 0;
}
+
/*
* hw_params callback
*/
@@ -296,8 +372,6 @@ 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;
@@ -318,19 +392,18 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
return -ENOMEM;
buf->bpl = chip->period_size;
+ chip->buf = buf;
- dma = &buf->dma;
- videobuf_dma_init(dma);
- ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
+ ret = cx23885_alsa_dma_init(chip,
(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
if (ret < 0)
goto error;
- ret = videobuf_dma_map(&chip->pci->dev, dma);
+ ret = cx23885_alsa_dma_map(chip);
if (ret < 0)
goto error;
- ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
+ ret = cx23885_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
chip->period_size, chip->num_periods, 1);
if (ret < 0)
goto error;
@@ -340,10 +413,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
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_area = chip->buf->vaddr;
substream->runtime->dma_bytes = chip->dma_size;
substream->runtime->dma_addr = 0;
@@ -351,6 +421,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
error:
kfree(buf);
+ chip->buf = NULL;
return ret;
}
diff --git a/drivers/media/pci/cx23885/cx23885-av.c b/drivers/media/pci/cx23885/cx23885-av.c
index c443b7a..877dad8 100644
--- a/drivers/media/pci/cx23885/cx23885-av.c
+++ b/drivers/media/pci/cx23885/cx23885-av.c
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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"
diff --git a/drivers/media/pci/cx23885/cx23885-av.h b/drivers/media/pci/cx23885/cx23885-av.h
index d2915c3..97f232f 100644
--- a/drivers/media/pci/cx23885/cx23885-av.h
+++ b/drivers/media/pci/cx23885/cx23885-av.h
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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_
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index c2b6080..88c257d 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -679,6 +675,11 @@ struct cx23885_board cx23885_boards[] = {
.amux = CX25840_AUDIO7,
} },
},
+ [CX23885_BOARD_DVBSKY_T9580] = {
+ .name = "DVBSky T9580",
+ .portb = CX23885_MPEG_DVB,
+ .portc = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -934,6 +935,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x18ac,
.subdevice = 0xdb98,
.card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2,
+ }, {
+ .subvendor = 0x4254,
+ .subdevice = 0x9580,
+ .card = CX23885_BOARD_DVBSKY_T9580,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -1528,6 +1533,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx_set(GP0_IO, 0x00040004);
mdelay(60);
break;
+ case CX23885_BOARD_DVBSKY_T9580:
+ /* enable GPIO3-18 pins */
+ cx_write(MC417_CTL, 0x00000037);
+ cx23885_gpio_enable(dev, GPIO_2 | GPIO_11, 1);
+ cx23885_gpio_clear(dev, GPIO_2 | GPIO_11);
+ mdelay(100);
+ cx23885_gpio_set(dev, GPIO_2 | GPIO_11);
+ break;
}
}
@@ -1851,6 +1864,14 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
+ case CX23885_BOARD_DVBSKY_T9580:
+ 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 = 0x8; /* Serial bus */
+ 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:
@@ -1913,6 +1934,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_AVERMEDIA_HC81R:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
+ case CX23885_BOARD_DVBSKY_T9580:
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[2].i2c_adap,
"cx25840", 0x88 >> 1, NULL);
@@ -1970,5 +1992,3 @@ void cx23885_card_setup(struct cx23885_dev *dev)
}
}
}
-
-/* ------------------------------------------------------------------ */
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index edcd79d..331edda 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -420,39 +416,23 @@ static int cx23885_risc_decode(u32 risc)
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
-void cx23885_wakeup(struct cx23885_tsport *port,
+static 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;
- v4l2_get_timestamp(&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);
+ return;
+ buf = list_entry(q->active.next,
+ struct cx23885_buffer, queue);
+
+ v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ buf->vb.v4l2_buf.sequence = q->count++;
+ dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
+ count, q->count);
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
}
int cx23885_sram_channel_setup(struct cx23885_dev *dev,
@@ -482,8 +462,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
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 + 0, RISC_JUMP | RISC_CNT_RESET);
+ cx_write(8 + 4, 12);
cx_write(8 + 8, 0);
/* write CDT */
@@ -590,7 +570,7 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev,
}
static void cx23885_risc_disasm(struct cx23885_tsport *port,
- struct btcx_riscmem *risc)
+ struct cx23885_riscmem *risc)
{
struct cx23885_dev *dev = port->dev;
unsigned int i, j, n;
@@ -699,10 +679,6 @@ static int get_resources(struct cx23885_dev *dev)
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)
{
@@ -719,11 +695,6 @@ static int cx23885_init_tsport(struct cx23885_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;
@@ -776,9 +747,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
BUG();
}
- cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
- port->reg_dma_ctl, port->dma_ctl_val, 0x00);
-
return 0;
}
@@ -1089,11 +1057,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
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)
+ unsigned int lines, unsigned int lpi, bool jump)
{
struct scatterlist *sg;
unsigned int line, todo, sol;
+
+ if (jump) {
+ *(rp++) = cpu_to_le32(RISC_JUMP);
+ *(rp++) = cpu_to_le32(0);
+ *(rp++) = cpu_to_le32(0); /* bits 63-32 */
+ }
+
/* sync instruction */
if (sync_line != NO_SYNC_LINE)
*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
@@ -1146,14 +1121,13 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
return rp;
}
-int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+int cx23885_risc_buffer(struct pci_dev *pci, struct cx23885_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)
@@ -1168,19 +1142,20 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
/* 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;
+ instructions += 5;
+ risc->size = instructions * 12;
+ risc->cpu = pci_alloc_consistent(pci, risc->size, &risc->dma);
+ if (risc->cpu == NULL)
+ return -ENOMEM;
/* write risc instructions */
rp = risc->cpu;
if (UNSET != top_offset)
rp = cx23885_risc_field(rp, sglist, top_offset, 0,
- bpl, padding, lines, 0);
+ bpl, padding, lines, 0, true);
if (UNSET != bottom_offset)
rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
- bpl, padding, lines, 0);
+ bpl, padding, lines, 0, UNSET == top_offset);
/* save pointer to jmp instruction address */
risc->jmp = rp;
@@ -1189,14 +1164,13 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
}
int cx23885_risc_databuffer(struct pci_dev *pci,
- struct btcx_riscmem *risc,
+ struct cx23885_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
@@ -1204,16 +1178,17 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
than PAGE_SIZE */
/* Jump and write need an extra dword */
instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
- instructions += 1;
+ instructions += 4;
- rc = btcx_riscmem_alloc(pci, risc, instructions*12);
- if (rc < 0)
- return rc;
+ risc->size = instructions * 12;
+ risc->cpu = pci_alloc_consistent(pci, risc->size, &risc->dma);
+ if (risc->cpu == NULL)
+ return -ENOMEM;
/* write risc instructions */
rp = risc->cpu;
rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE,
- bpl, 0, lines, lpi);
+ bpl, 0, lines, lpi, lpi == 0);
/* save pointer to jmp instruction address */
risc->jmp = rp;
@@ -1221,14 +1196,13 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
return 0;
}
-int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+int cx23885_risc_vbibuffer(struct pci_dev *pci, struct cx23885_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)
@@ -1243,22 +1217,23 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
/* 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;
+ instructions += 5;
+ risc->size = instructions * 12;
+ risc->cpu = pci_alloc_consistent(pci, risc->size, &risc->dma);
+ if (risc->cpu == NULL)
+ return -ENOMEM;
/* 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);
+ rp = cx23885_risc_field(rp, sglist, top_offset, 0,
+ bpl, padding, lines, 0, true);
if (UNSET != bottom_offset)
- rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
- bpl, padding, lines, 0);
+ rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
+ bpl, padding, lines, 0, UNSET == top_offset);
@@ -1269,38 +1244,12 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
}
-int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value)
+void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
{
- __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);
+ struct cx23885_riscmem *risc = &buf->risc;
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;
+ pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma);
}
static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
@@ -1355,7 +1304,7 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk));
}
-static int cx23885_start_dma(struct cx23885_tsport *port,
+int cx23885_start_dma(struct cx23885_tsport *port,
struct cx23885_dmaqueue *q,
struct cx23885_buffer *buf)
{
@@ -1363,7 +1312,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
u32 reg;
dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
- buf->vb.width, buf->vb.height, buf->vb.field);
+ dev->width, dev->height, dev->field);
/* Stop the fifo and risc engine for this port */
cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
@@ -1379,7 +1328,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
}
/* write TS length to chip */
- cx_write(port->reg_lngth, buf->vb.width);
+ cx_write(port->reg_lngth, port->ts_packet_size);
if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
(!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) {
@@ -1408,7 +1357,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
/* NOTE: this is 2 (reserved) for portb, does it matter? */
/* reset counter to zero */
cx_write(port->reg_gpcnt_ctl, 3);
- q->count = 1;
+ q->count = 0;
/* Set VIDB pins to input */
if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
@@ -1497,134 +1446,83 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
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_move_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_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);
- /* 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)
+int cx23885_buf_prepare(struct cx23885_buffer *buf, struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
int size = port->ts_packet_size * port->ts_packet_count;
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
int rc;
dprintk(1, "%s: %p\n", __func__, buf);
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
+ if (vb2_plane_size(&buf->vb, 0) < size)
return -EINVAL;
+ vb2_set_plane_payload(&buf->vb, 0, size);
- 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;
+ rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
+ if (!rc)
+ return -EIO;
- fail:
- cx23885_free_buffer(q, buf);
- return rc;
+ cx23885_risc_databuffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ port->ts_packet_size, port->ts_packet_count, 0);
+ return 0;
}
+/*
+ * The risc program for each buffer works as follows: it starts with a simple
+ * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
+ * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
+ * the initial JUMP).
+ *
+ * This is the risc program of the first buffer to be queued if the active list
+ * is empty and it just keeps DMAing this buffer without generating any
+ * interrupts.
+ *
+ * If a new buffer is added then the initial JUMP in the code for that buffer
+ * will generate an interrupt which signals that the previous buffer has been
+ * DMAed successfully and that it can be returned to userspace.
+ *
+ * It also sets the final jump of the previous buffer to the start of the new
+ * buffer, thus chaining the new buffer into the DMA chain. This is a single
+ * atomic u32 write, so there is no race condition.
+ *
+ * The end-result of all this that you only get an interrupt when a buffer
+ * is ready, so the control flow is very easy.
+ */
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;
+ unsigned long flags;
- /* 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.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
+ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
+ buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
+ spin_lock_irqsave(&dev->slock, flags);
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);
+ list_add_tail(&buf->queue, &cx88q->active);
dprintk(1, "[%p/%d] %s - first active\n",
- buf, buf->vb.i, __func__);
+ buf, buf->vb.v4l2_buf.index, __func__);
} else {
- dprintk(1, "queue is not empty - append to active\n");
+ buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
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++;
+ queue);
+ list_add_tail(&buf->queue, &cx88q->active);
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__);
+ buf, buf->vb.v4l2_buf.index, __func__);
}
+ spin_unlock_irqrestore(&dev->slock, flags);
}
/* ----------------------------------------------------------- */
-static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
- int restart)
+static void do_cancel_buffers(struct cx23885_tsport *port, char *reason)
{
struct cx23885_dev *dev = port->dev;
struct cx23885_dmaqueue *q = &port->mpegq;
@@ -1634,16 +1532,11 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
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);
+ queue);
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
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);
+ buf, buf->vb.v4l2_buf.index, reason, (unsigned long)buf->risc.dma);
}
spin_unlock_irqrestore(&port->slock, flags);
}
@@ -1651,27 +1544,10 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
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);
+ do_cancel_buffers(port, "cancel");
}
int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
@@ -1721,11 +1597,6 @@ int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
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);
@@ -1777,14 +1648,6 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
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);
@@ -2087,6 +1950,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
struct cx23885_dev *dev;
+ struct v4l2_ctrl_handler *hdl;
int err;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -2097,6 +1961,14 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
if (err < 0)
goto fail_free;
+ hdl = &dev->ctrl_handler;
+ v4l2_ctrl_handler_init(hdl, 6);
+ if (hdl->error) {
+ err = hdl->error;
+ goto fail_ctrl;
+ }
+ dev->v4l2_dev.ctrl_handler = hdl;
+
/* Prepare to handle notifications from subdevices */
cx23885_v4l2_dev_notify_init(dev);
@@ -2104,12 +1976,12 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
err = -EIO;
- goto fail_unreg;
+ goto fail_ctrl;
}
if (cx23885_dev_setup(dev) < 0) {
err = -EINVAL;
- goto fail_unreg;
+ goto fail_ctrl;
}
/* print pci info */
@@ -2157,7 +2029,8 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
fail_irq:
cx23885_dev_unregister(dev);
-fail_unreg:
+fail_ctrl:
+ v4l2_ctrl_handler_free(hdl);
v4l2_device_unregister(&dev->v4l2_dev);
fail_free:
kfree(dev);
@@ -2180,6 +2053,7 @@ static void cx23885_finidev(struct pci_dev *pci_dev)
free_irq(pci_dev->irq, dev);
cx23885_dev_unregister(dev);
+ v4l2_ctrl_handler_free(&dev->ctrl_handler);
v4l2_device_unregister(v4l2_dev);
kfree(dev);
}
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 968fecc..13734b8 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -73,6 +69,10 @@
#include "a8293.h"
#include "mb86a20s.h"
#include "si2165.h"
+#include "si2168.h"
+#include "si2157.h"
+#include "m88ds3103.h"
+#include "m88ts2022.h"
static unsigned int debug;
@@ -91,59 +91,95 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/* ------------------------------------------------------------------ */
-static int dvb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], void *alloc_ctxs[])
{
- struct cx23885_tsport *port = q->priv_data;
+ struct cx23885_tsport *port = q->drv_priv;
port->ts_packet_size = 188 * 4;
port->ts_packet_count = 32;
-
- *size = port->ts_packet_size * port->ts_packet_count;
- *count = 32;
+ *num_planes = 1;
+ sizes[0] = port->ts_packet_size * port->ts_packet_count;
+ *num_buffers = 32;
return 0;
}
-static int dvb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
+
+static int buffer_prepare(struct vb2_buffer *vb)
{
- struct cx23885_tsport *port = q->priv_data;
- return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
+ struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf =
+ container_of(vb, struct cx23885_buffer, vb);
+
+ return cx23885_buf_prepare(buf, port);
}
-static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
{
- struct cx23885_tsport *port = q->priv_data;
- cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
+ struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
+ struct cx23885_dev *dev = port->dev;
+ struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer, vb);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+ cx23885_free_buffer(dev, buf);
+
+ dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
}
-static void dvb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
+static void buffer_queue(struct vb2_buffer *vb)
{
- cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
+ struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer, vb);
+
+ cx23885_buf_queue(port, buf);
}
static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open)
{
- struct videobuf_dvb_frontends *f;
- struct videobuf_dvb_frontend *fe;
+ struct vb2_dvb_frontends *f;
+ struct vb2_dvb_frontend *fe;
f = &port->frontends;
if (f->gate <= 1) /* undefined or fe0 */
- fe = videobuf_dvb_get_frontend(f, 1);
+ fe = vb2_dvb_get_frontend(f, 1);
else
- fe = videobuf_dvb_get_frontend(f, f->gate);
+ fe = vb2_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 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 cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct cx23885_tsport *port = q->drv_priv;
+ struct cx23885_dmaqueue *dmaq = &port->mpegq;
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
+
+ cx23885_start_dma(port, dmaq, buf);
+ return 0;
+}
+
+static void cx23885_stop_streaming(struct vb2_queue *q)
+{
+ struct cx23885_tsport *port = q->drv_priv;
+
+ cx23885_cancel_buffers(port);
+}
+
+static struct vb2_ops dvb_qops = {
+ .queue_setup = queue_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_finish = buffer_finish,
+ .buf_queue = buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = cx23885_start_streaming,
+ .stop_streaming = cx23885_stop_streaming,
};
static struct s5h1409_config hauppauge_generic_config = {
@@ -551,6 +587,35 @@ static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
return 0;
}
+static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
+
+ switch (voltage) {
+ case SEC_VOLTAGE_13:
+ cx23885_gpio_set(dev, GPIO_1);
+ cx23885_gpio_clear(dev, GPIO_0);
+ break;
+ case SEC_VOLTAGE_18:
+ cx23885_gpio_set(dev, GPIO_1);
+ cx23885_gpio_set(dev, GPIO_0);
+ break;
+ case SEC_VOLTAGE_OFF:
+ cx23885_gpio_clear(dev, GPIO_1);
+ cx23885_gpio_clear(dev, GPIO_0);
+ break;
+ }
+
+ /* call the frontend set_voltage function */
+ port->fe_set_voltage(fe, voltage);
+
+ return 0;
+}
+
static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
@@ -715,6 +780,19 @@ static const struct si2165_config hauppauge_hvr4400_si2165_config = {
.ref_freq_Hz = 16000000,
};
+static const struct m88ds3103_config dvbsky_t9580_m88ds3103_config = {
+ .i2c_addr = 0x68,
+ .clock = 27000000,
+ .i2c_wr_max = 33,
+ .clock_out = 0,
+ .ts_mode = M88DS3103_TS_PARALLEL,
+ .ts_clk = 16000,
+ .ts_clk_pol = 1,
+ .lnb_en_pol = 1,
+ .lnb_hv_pol = 0,
+ .agc = 0x99,
+};
+
static int netup_altera_fpga_rw(void *device, int flag, int data, int read)
{
struct cx23885_dev *dev = (struct cx23885_dev *)device;
@@ -863,16 +941,23 @@ static int dvb_register(struct cx23885_tsport *port)
struct dib7000p_ops dib7000p_ops;
struct cx23885_dev *dev = port->dev;
struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
- struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+ struct vb2_dvb_frontend *fe0, *fe1 = NULL;
+ struct si2168_config si2168_config;
+ struct si2157_config si2157_config;
+ struct m88ts2022_config m88ts2022_config;
+ struct i2c_board_info info;
+ struct i2c_adapter *adapter;
+ struct i2c_client *client_demod;
+ struct i2c_client *client_tuner;
int mfe_shared = 0; /* bus not shared by default */
int ret;
/* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+ fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
if (!fe0)
return -EINVAL;
- /* init struct videobuf_dvb */
+ /* init struct vb2_dvb */
fe0->dvb.name = dev->name;
/* multi-frontend gate control is undefined or defaults to fe0 */
@@ -1392,7 +1477,7 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
}
/* MFE frontend 2 */
- fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
+ fe1 = vb2_dvb_get_frontend(&port->frontends, 2);
if (fe1 == NULL)
goto frontend_detach;
/* DVB-C init */
@@ -1491,7 +1576,7 @@ static int dvb_register(struct cx23885_tsport *port)
&hauppauge_hvr4400_si2165_config,
&i2c_bus->i2c_adap);
if (fe0->dvb.frontend != NULL) {
- fe0->dvb.frontend->ops.i2c_gate_ctrl = 0;
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
if (!dvb_attach(tda18271_attach,
fe0->dvb.frontend,
0x60, &i2c_bus2->i2c_adap,
@@ -1501,6 +1586,97 @@ static int dvb_register(struct cx23885_tsport *port)
break;
}
break;
+ case CX23885_BOARD_DVBSKY_T9580:
+ i2c_bus = &dev->i2c_bus[0];
+ i2c_bus2 = &dev->i2c_bus[1];
+ switch (port->nr) {
+ /* port b - satellite */
+ case 1:
+ /* attach frontend */
+ fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
+ &dvbsky_t9580_m88ds3103_config,
+ &i2c_bus2->i2c_adap, &adapter);
+ if (fe0->dvb.frontend == NULL)
+ break;
+
+ /* attach tuner */
+ m88ts2022_config.fe = fe0->dvb.frontend;
+ m88ts2022_config.clock = 27000000;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &m88ts2022_config;
+ request_module(info.type);
+ client_tuner = i2c_new_device(adapter, &info);
+ if (client_tuner == NULL ||
+ client_tuner->dev.driver == NULL)
+ goto frontend_detach;
+ if (!try_module_get(client_tuner->dev.driver->owner)) {
+ i2c_unregister_device(client_tuner);
+ goto frontend_detach;
+ }
+
+ /* delegate signal strength measurement to tuner */
+ fe0->dvb.frontend->ops.read_signal_strength =
+ fe0->dvb.frontend->ops.tuner_ops.get_rf_strength;
+
+ /*
+ * for setting the voltage we need to set GPIOs on
+ * the card.
+ */
+ port->fe_set_voltage =
+ fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage =
+ dvbsky_t9580_set_voltage;
+
+ port->i2c_client_tuner = client_tuner;
+
+ break;
+ /* port c - terrestrial/cable */
+ case 2:
+ /* attach frontend */
+ si2168_config.i2c_adapter = &adapter;
+ si2168_config.fe = &fe0->dvb.frontend;
+ si2168_config.ts_mode = SI2168_TS_SERIAL;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+ info.addr = 0x64;
+ info.platform_data = &si2168_config;
+ request_module(info.type);
+ client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
+ if (client_demod == NULL ||
+ client_demod->dev.driver == NULL)
+ goto frontend_detach;
+ if (!try_module_get(client_demod->dev.driver->owner)) {
+ i2c_unregister_device(client_demod);
+ goto frontend_detach;
+ }
+ port->i2c_client_demod = client_demod;
+
+ /* attach tuner */
+ si2157_config.fe = fe0->dvb.frontend;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &si2157_config;
+ request_module(info.type);
+ client_tuner = i2c_new_device(adapter, &info);
+ if (client_tuner == NULL ||
+ client_tuner->dev.driver == NULL) {
+ module_put(client_demod->dev.driver->owner);
+ i2c_unregister_device(client_demod);
+ goto frontend_detach;
+ }
+ if (!try_module_get(client_tuner->dev.driver->owner)) {
+ i2c_unregister_device(client_tuner);
+ module_put(client_demod->dev.driver->owner);
+ i2c_unregister_device(client_demod);
+ goto frontend_detach;
+ }
+ port->i2c_client_tuner = client_tuner;
+ break;
+ }
+ break;
default:
printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
" isn't supported yet\n",
@@ -1532,7 +1708,7 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
/* register everything */
- ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+ ret = vb2_dvb_register_bus(&port->frontends, THIS_MODULE, port,
&dev->pci->dev, adapter_nr, mfe_shared);
if (ret)
goto frontend_detach;
@@ -1575,20 +1751,36 @@ static int dvb_register(struct cx23885_tsport *port)
memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6);
break;
}
+ case CX23885_BOARD_DVBSKY_T9580: {
+ u8 eeprom[256]; /* 24C02 i2c eeprom */
+
+ if (port->nr > 2)
+ 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 "DVBSky T9580 port %d MAC address: %pM\n",
+ port->nr, eeprom + 0xc0 + (port->nr-1) * 8);
+ memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 +
+ (port->nr-1) * 8, 6);
+ break;
+ }
}
return ret;
frontend_detach:
port->gate_ctrl = NULL;
- videobuf_dvb_dealloc_frontends(&port->frontends);
+ vb2_dvb_dealloc_frontends(&port->frontends);
return -EINVAL;
}
int cx23885_dvb_register(struct cx23885_tsport *port)
{
- struct videobuf_dvb_frontend *fe0;
+ struct vb2_dvb_frontend *fe0;
struct cx23885_dev *dev = port->dev;
int err, i;
@@ -1605,13 +1797,15 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
port->num_frontends);
for (i = 1; i <= port->num_frontends; i++) {
- if (videobuf_dvb_alloc_frontend(
+ struct vb2_queue *q;
+
+ if (vb2_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);
+ fe0 = vb2_dvb_get_frontend(&port->frontends, i);
if (!fe0)
err = -EINVAL;
@@ -1627,10 +1821,21 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
/* 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);
+ q = &fe0->dvb.dvbq;
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+ q->gfp_flags = GFP_DMA32;
+ q->min_buffers_needed = 2;
+ q->drv_priv = port;
+ q->buf_struct_size = sizeof(struct cx23885_buffer);
+ q->ops = &dvb_qops;
+ q->mem_ops = &vb2_dma_sg_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &dev->lock;
+
+ err = vb2_queue_init(q);
+ if (err < 0)
+ return err;
}
err = dvb_register(port);
if (err != 0)
@@ -1642,18 +1847,27 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
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);
+ struct vb2_dvb_frontend *fe0;
+ struct i2c_client *client;
+
+ /* remove I2C client for tuner */
+ client = port->i2c_client_tuner;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ /* remove I2C client for demodulator */
+ client = port->i2c_client_demod;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
+
if (fe0 && fe0->dvb.frontend)
- videobuf_dvb_unregister_bus(&port->frontends);
+ vb2_dvb_unregister_bus(&port->frontends);
switch (port->dev->board) {
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
@@ -1668,4 +1882,3 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
return 0;
}
-
diff --git a/drivers/media/pci/cx23885/cx23885-f300.c b/drivers/media/pci/cx23885/cx23885-f300.c
index 5444cc5..6f817d8 100644
--- a/drivers/media/pci/cx23885/cx23885-f300.c
+++ b/drivers/media/pci/cx23885/cx23885-f300.c
@@ -22,10 +22,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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"
diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c
index 4887314..fd71306 100644
--- a/drivers/media/pci/cx23885/cx23885-i2c.c
+++ b/drivers/media/pci/cx23885/cx23885-i2c.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -386,11 +382,3 @@ void cx23885_av_clk(struct cx23885_dev *dev, int enable)
i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1);
}
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 1940c18..9d37fe6 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -28,11 +28,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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>
diff --git a/drivers/media/pci/cx23885/cx23885-input.h b/drivers/media/pci/cx23885/cx23885-input.h
index 87dc44e..6199c7e 100644
--- a/drivers/media/pci/cx23885/cx23885-input.h
+++ b/drivers/media/pci/cx23885/cx23885-input.h
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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_
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c
index 271d69d..d2cdd40 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.c
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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"
@@ -28,7 +24,7 @@
int cx23885_g_chip_info(struct file *file, void *fh,
struct v4l2_dbg_chip_info *chip)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
if (chip->match.addr > 1)
return -EINVAL;
@@ -64,7 +60,7 @@ static int cx23417_g_register(struct cx23885_dev *dev,
int cx23885_g_register(struct file *file, void *fh,
struct v4l2_dbg_register *reg)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
if (reg->match.addr > 1)
return -EINVAL;
@@ -96,7 +92,7 @@ static int cx23417_s_register(struct cx23885_dev *dev,
int cx23885_s_register(struct file *file, void *fh,
const struct v4l2_dbg_register *reg)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
if (reg->match.addr > 1)
return -EINVAL;
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.h b/drivers/media/pci/cx23885/cx23885-ioctl.h
index 92d9f07..cc5dbb6 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.h
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.h
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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_
diff --git a/drivers/media/pci/cx23885/cx23885-ir.c b/drivers/media/pci/cx23885/cx23885-ir.c
index bfef193..89dc4cc 100644
--- a/drivers/media/pci/cx23885/cx23885-ir.c
+++ b/drivers/media/pci/cx23885/cx23885-ir.c
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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>
diff --git a/drivers/media/pci/cx23885/cx23885-ir.h b/drivers/media/pci/cx23885/cx23885-ir.h
index 0c9d8bd..8e93d1f 100644
--- a/drivers/media/pci/cx23885/cx23885-ir.h
+++ b/drivers/media/pci/cx23885/cx23885-ir.h
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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_
diff --git a/drivers/media/pci/cx23885/cx23885-reg.h b/drivers/media/pci/cx23885/cx23885-reg.h
index a99936e..2d3cbaf 100644
--- a/drivers/media/pci/cx23885/cx23885-reg.h
+++ b/drivers/media/pci/cx23885/cx23885-reg.h
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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_
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index a1154f0..a7c6ef8 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -42,33 +38,32 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
/* ------------------------------------------------------------------ */
#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)
+#define VBI_NTSC_LINE_COUNT 12
+#define VBI_PAL_LINE_COUNT 18
int cx23885_vbi_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
+ f->fmt.vbi.sampling_rate = 27000000;
+ 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;
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;
+ f->fmt.vbi.start[0] = V4L2_VBI_ITU_525_F1_START + 9;
+ f->fmt.vbi.start[1] = V4L2_VBI_ITU_525_F2_START + 9;
+ f->fmt.vbi.count[0] = VBI_NTSC_LINE_COUNT;
+ f->fmt.vbi.count[1] = VBI_NTSC_LINE_COUNT;
} 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;
+ f->fmt.vbi.start[0] = V4L2_VBI_ITU_625_F1_START + 5;
+ f->fmt.vbi.start[1] = V4L2_VBI_ITU_625_F2_START + 5;
+ f->fmt.vbi.count[0] = VBI_PAL_LINE_COUNT;
+ f->fmt.vbi.count[1] = VBI_PAL_LINE_COUNT;
}
return 0;
@@ -94,15 +89,6 @@ int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status)
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;
}
@@ -114,13 +100,13 @@ static int cx23885_start_vbi_dma(struct cx23885_dev *dev,
/* setup fifo + format */
cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02],
- buf->vb.width, buf->risc.dma);
+ VBI_LINE_LENGTH, 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;
+ q->count = 0;
/* enable irq */
cx23885_irq_add_enable(dev, 0x01);
@@ -133,163 +119,153 @@ static int cx23885_start_vbi_dma(struct cx23885_dev *dev,
return 0;
}
+/* ------------------------------------------------------------------ */
-int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], void *alloc_ctxs[])
{
- 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));
+ struct cx23885_dev *dev = q->drv_priv;
+ unsigned lines = VBI_PAL_LINE_COUNT;
+
+ if (dev->tvnorm & V4L2_STD_525_60)
+ lines = VBI_NTSC_LINE_COUNT;
+ *num_planes = 1;
+ sizes[0] = lines * VBI_LINE_LENGTH * 2;
return 0;
}
-void cx23885_vbi_timeout(unsigned long data)
+static int buffer_prepare(struct vb2_buffer *vb)
{
- struct cx23885_dev *dev = (struct cx23885_dev *)data;
- struct cx23885_dmaqueue *q = &dev->vbiq;
- struct cx23885_buffer *buf;
- unsigned long flags;
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer, vb);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+ unsigned lines = VBI_PAL_LINE_COUNT;
+ int ret;
- /* Stop the VBI engine */
- cx_clear(VID_A_DMA_CTL, 0x22);
+ if (dev->tvnorm & V4L2_STD_525_60)
+ lines = VBI_NTSC_LINE_COUNT;
- 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);
-}
+ if (vb2_plane_size(vb, 0) < lines * VBI_LINE_LENGTH * 2)
+ return -EINVAL;
+ vb2_set_plane_payload(vb, 0, lines * VBI_LINE_LENGTH * 2);
-/* ------------------------------------------------------------------ */
-#define VBI_LINE_LENGTH 1440
-#define VBI_LINE_COUNT 17
+ ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
+ if (!ret)
+ return -EIO;
-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;
+ cx23885_risc_vbibuffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ 0, VBI_LINE_LENGTH * lines,
+ VBI_LINE_LENGTH, 0,
+ lines);
return 0;
}
-static int
-vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
+static void buffer_finish(struct vb2_buffer *vb)
{
- struct cx23885_fh *fh = q->priv_data;
- struct cx23885_dev *dev = fh->dev;
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
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;
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
- 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;
+ cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
- fail:
- cx23885_free_buffer(q, buf);
- return rc;
+ dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
}
-static void
-vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+/*
+ * The risc program for each buffer works as follows: it starts with a simple
+ * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
+ * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
+ * the initial JUMP).
+ *
+ * This is the risc program of the first buffer to be queued if the active list
+ * is empty and it just keeps DMAing this buffer without generating any
+ * interrupts.
+ *
+ * If a new buffer is added then the initial JUMP in the code for that buffer
+ * will generate an interrupt which signals that the previous buffer has been
+ * DMAed successfully and that it can be returned to userspace.
+ *
+ * It also sets the final jump of the previous buffer to the start of the new
+ * buffer, thus chaining the new buffer into the DMA chain. This is a single
+ * atomic u32 write, so there is no race condition.
+ *
+ * The end-result of all this that you only get an interrupt when a buffer
+ * is ready, so the control flow is very easy.
+ */
+static void buffer_queue(struct vb2_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);
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb);
+ struct cx23885_buffer *prev;
+ struct cx23885_dmaqueue *q = &dev->vbiq;
+ unsigned long flags;
+
+ buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
+ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
+ buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
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));
+ spin_lock_irqsave(&dev->slock, flags);
+ list_add_tail(&buf->queue, &q->active);
+ spin_unlock_irqrestore(&dev->slock, flags);
dprintk(2, "[%p/%d] vbi_queue - first active\n",
- buf, buf->vb.i);
+ buf, buf->vb.v4l2_buf.index);
} else {
+ buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
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++;
+ queue);
+ spin_lock_irqsave(&dev->slock, flags);
+ list_add_tail(&buf->queue, &q->active);
+ spin_unlock_irqrestore(&dev->slock, flags);
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);
+ buf, buf->vb.v4l2_buf.index);
}
}
-static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
{
- struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
+ struct cx23885_dev *dev = q->drv_priv;
+ struct cx23885_dmaqueue *dmaq = &dev->vbiq;
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
- cx23885_free_buffer(q, buf);
+ cx23885_start_vbi_dma(dev, dmaq, buf);
+ return 0;
}
-struct videobuf_queue_ops cx23885_vbi_qops = {
- .buf_setup = vbi_setup,
- .buf_prepare = vbi_prepare,
- .buf_queue = vbi_queue,
- .buf_release = vbi_release,
-};
+static void cx23885_stop_streaming(struct vb2_queue *q)
+{
+ struct cx23885_dev *dev = q->drv_priv;
+ struct cx23885_dmaqueue *dmaq = &dev->vbiq;
+ unsigned long flags;
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+ cx_clear(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */
+ spin_lock_irqsave(&dev->slock, flags);
+ while (!list_empty(&dmaq->active)) {
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
+
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ }
+ spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+
+struct vb2_ops cx23885_vbi_qops = {
+ .queue_setup = queue_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_finish = buffer_finish,
+ .buf_queue = buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = cx23885_start_streaming,
+ .stop_streaming = cx23885_stop_streaming,
+};
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 91e4cb4..682a4f9 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -35,6 +31,7 @@
#include "cx23885-video.h"
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
#include "cx23885-ioctl.h"
#include "tuner-xc2028.h"
@@ -48,15 +45,12 @@ 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);
@@ -79,77 +73,14 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
/* 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)
{
@@ -158,163 +89,27 @@ static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
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;
-
- v4l2_get_timestamp(&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);
+ return;
+ buf = list_entry(q->active.next,
+ struct cx23885_buffer, queue);
+
+ buf->vb.v4l2_buf.sequence = q->count++;
+ v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
+ count, q->count);
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
}
int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
@@ -324,6 +119,12 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
(unsigned int)norm,
v4l2_norm_to_name(norm));
+ if (dev->tvnorm != norm) {
+ if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
+ vb2_is_busy(&dev->vb2_mpegq))
+ return -EBUSY;
+ }
+
dev->tvnorm = norm;
call_all(dev, video, s_std, norm);
@@ -345,79 +146,13 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
*vfd = *template;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
+ vfd->lock = &dev->lock;
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);
-}
-
int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
{
/* 8 bit registers, 8 bit values */
@@ -567,7 +302,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
/* reset counter */
cx_write(VID_A_GPCNT_CTL, 3);
- q->count = 1;
+ q->count = 0;
/* enable irq */
cx23885_irq_add_enable(dev, 0x01);
@@ -580,479 +315,206 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
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)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], void *alloc_ctxs[])
{
- struct cx23885_fh *fh = q->priv_data;
+ struct cx23885_dev *dev = q->drv_priv;
- *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;
+ *num_planes = 1;
+ sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3;
return 0;
}
-static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb)
{
- struct cx23885_fh *fh = q->priv_data;
- struct cx23885_dev *dev = fh->dev;
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
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);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
int field_tff;
+ int ret;
- 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)
+ buf->bpl = (dev->width * dev->fmt->depth) >> 3;
+
+ if (vb2_plane_size(vb, 0) < dev->height * buf->bpl)
return -EINVAL;
+ vb2_set_plane_payload(vb, 0, dev->height * buf->bpl);
- 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;
- }
+ ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
+ if (!ret)
+ return -EIO;
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- init_buffer = 1;
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (0 != rc)
- goto fail;
- }
+ switch (dev->field) {
+ case V4L2_FIELD_TOP:
+ cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, 0, UNSET,
+ buf->bpl, 0, dev->height);
+ break;
+ case V4L2_FIELD_BOTTOM:
+ cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, UNSET, 0,
+ buf->bpl, 0, dev->height);
+ break;
+ case V4L2_FIELD_INTERLACED:
+ if (dev->tvnorm & V4L2_STD_525_60)
+ /* 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 (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",
+ 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",
+ 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();
+ line0_offset = 0;
+ line1_offset = buf->bpl;
}
+ cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, line0_offset,
+ line1_offset,
+ buf->bpl, buf->bpl,
+ dev->height >> 1);
+ break;
+ case V4L2_FIELD_SEQ_TB:
+ cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ 0, buf->bpl * (dev->height >> 1),
+ buf->bpl, 0,
+ dev->height >> 1);
+ break;
+ case V4L2_FIELD_SEQ_BT:
+ cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ buf->bpl * (dev->height >> 1), 0,
+ buf->bpl, 0,
+ dev->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,
+ dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
+ buf, buf->vb.v4l2_buf.index,
+ dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
(unsigned long)buf->risc.dma);
-
- buf->vb.state = VIDEOBUF_PREPARED;
return 0;
+}
+
+static void buffer_finish(struct vb2_buffer *vb)
+{
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer, vb);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+ cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
- fail:
- cx23885_free_buffer(q, buf);
- return rc;
+ dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
}
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+/*
+ * The risc program for each buffer works as follows: it starts with a simple
+ * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
+ * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
+ * the initial JUMP).
+ *
+ * This is the risc program of the first buffer to be queued if the active list
+ * is empty and it just keeps DMAing this buffer without generating any
+ * interrupts.
+ *
+ * If a new buffer is added then the initial JUMP in the code for that buffer
+ * will generate an interrupt which signals that the previous buffer has been
+ * DMAed successfully and that it can be returned to userspace.
+ *
+ * It also sets the final jump of the previous buffer to the start of the new
+ * buffer, thus chaining the new buffer into the DMA chain. This is a single
+ * atomic u32 write, so there is no race condition.
+ *
+ * The end-result of all this that you only get an interrupt when a buffer
+ * is ready, so the control flow is very easy.
+ */
+static void buffer_queue(struct vb2_buffer *vb)
{
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
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;
+ unsigned long flags;
- /* 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);
+ /* add jump to start */
+ buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
+ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
+ buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
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);
+ spin_lock_irqsave(&dev->slock, flags);
+ if (list_empty(&q->active)) {
+ list_add_tail(&buf->queue, &q->active);
dprintk(2, "[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.i);
-
+ buf, buf->vb.v4l2_buf.index);
} else {
+ buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
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;
+ queue);
+ list_add_tail(&buf->queue, &q->active);
+ prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+ dprintk(2, "[%p/%d] buffer_queue - append to active\n",
+ buf, buf->vb.v4l2_buf.index);
}
+ spin_unlock_irqrestore(&dev->slock, flags);
}
-static int video_open(struct file *file)
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
{
- 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");
+ struct cx23885_dev *dev = q->drv_priv;
+ struct cx23885_dmaqueue *dmaq = &dev->vidq;
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
+ cx23885_start_video_dma(dev, dmaq, buf);
return 0;
}
-static ssize_t video_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
+static void cx23885_stop_streaming(struct vb2_queue *q)
{
- 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);
- }
+ struct cx23885_dev *dev = q->drv_priv;
+ struct cx23885_dmaqueue *dmaq = &dev->vidq;
+ unsigned long flags;
- /* 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);
- }
+ cx_clear(VID_A_DMA_CTL, 0x11);
+ spin_lock_irqsave(&dev->slock, flags);
+ while (!list_empty(&dmaq->active)) {
+ struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+ struct cx23885_buffer, queue);
- /* 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);
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
}
-
- 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;
+ spin_unlock_irqrestore(&dev->slock, flags);
}
-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);
- }
-}
+static struct vb2_ops cx23885_video_qops = {
+ .queue_setup = queue_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_finish = buffer_finish,
+ .buf_queue = buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = cx23885_start_streaming,
+ .stop_streaming = cx23885_stop_streaming,
+};
/* ------------------------------------------------------------------ */
/* VIDEO IOCTLS */
@@ -1060,16 +522,17 @@ static void init_controls(struct cx23885_dev *dev)
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = video_drvdata(file);
- 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.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.field = dev->field;
+ f->fmt.pix.pixelformat = dev->fmt->fourcc;
f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fh->fmt->depth) >> 3;
+ (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;
}
@@ -1077,7 +540,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
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_dev *dev = video_drvdata(file);
struct cx23885_fmt *fmt;
enum v4l2_field field;
unsigned int maxw, maxh;
@@ -1102,9 +565,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
maxh = maxh / 2;
break;
case V4L2_FIELD_INTERLACED:
+ case V4L2_FIELD_SEQ_TB:
+ case V4L2_FIELD_SEQ_BT:
break;
default:
- return -EINVAL;
+ field = V4L2_FIELD_INTERLACED;
+ break;
}
f->fmt.pix.field = field;
@@ -1114,6 +580,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
(f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
return 0;
}
@@ -1121,8 +588,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
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 cx23885_dev *dev = video_drvdata(file);
struct v4l2_mbus_framefmt mbus_fmt;
int err;
@@ -1131,34 +597,44 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
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;
+
+ if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
+ vb2_is_busy(&dev->vb2_mpegq))
+ return -EBUSY;
+
+ dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ dev->width = f->fmt.pix.width;
+ dev->height = f->fmt.pix.height;
+ dev->field = f->fmt.pix.field;
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
- fh->width, fh->height, fh->vidq.field);
+ dev->width, dev->height, dev->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);
+ /* s_mbus_fmt overwrites f->fmt.pix.field, restore it */
+ f->fmt.pix.field = dev->field;
return 0;
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
+ struct video_device *vdev = video_devdata(file);
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;
+ cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO;
if (dev->tuner_type != TUNER_ABSENT)
- cap->capabilities |= V4L2_CAP_TUNER;
+ cap->device_caps |= V4L2_CAP_TUNER;
+ if (vdev->vfl_type == VFL_TYPE_VBI)
+ cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
+ else
+ cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_VBI_CAPTURE |
+ V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -1175,85 +651,9 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
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;
+ struct cx23885_dev *dev = video_drvdata(file);
dprintk(1, "%s()\n", __func__);
*id = dev->tvnorm;
@@ -1262,14 +662,10 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
dprintk(1, "%s()\n", __func__);
- mutex_lock(&dev->lock);
- cx23885_set_tvnorm(dev, tvnorms);
- mutex_unlock(&dev->lock);
-
- return 0;
+ return cx23885_set_tvnorm(dev, tvnorms);
}
int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
@@ -1299,16 +695,16 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name, iname[INPUT(n)->type]);
+ i->std = CX23885_NORMS;
if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) ||
(CX23885_VMUX_CABLE == INPUT(n)->type)) {
i->type = V4L2_INPUT_TYPE_TUNER;
- i->std = CX23885_NORMS;
+ i->audioset = 4;
+ } else {
+ /* Two selectable audio inputs for non-tv inputs */
+ i->audioset = 3;
}
- /* 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
@@ -1324,14 +720,14 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
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;
+ struct cx23885_dev *dev = video_drvdata(file);
*i = dev->input;
dprintk(1, "%s() returns %d\n", __func__, *i);
@@ -1345,7 +741,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
int cx23885_set_input(struct file *file, void *priv, unsigned int i)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
dprintk(1, "%s(%d)\n", __func__, i);
@@ -1357,13 +753,11 @@ int cx23885_set_input(struct file *file, void *priv, unsigned int i)
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;
}
@@ -1374,39 +768,32 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
static int vidioc_log_status(struct file *file, void *priv)
{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
- 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;
+ struct cx23885_dev *dev = video_drvdata(file);
static const char *iname[] = {
[0] = "Baseband L/R 1",
[1] = "Baseband L/R 2",
+ [2] = "TV",
};
unsigned int n;
dprintk(1, "%s()\n", __func__);
n = i->index;
- if (n >= 2)
+ if (n >= 3)
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;
+ i->capability = V4L2_AUDCAP_STEREO;
return 0;
}
@@ -1420,9 +807,13 @@ static int vidioc_enum_audinput(struct file *file, void *priv,
static int vidioc_g_audinput(struct file *file, void *priv,
struct v4l2_audio *i)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
- i->index = dev->audinput;
+ if ((CX23885_VMUX_TELEVISION == INPUT(dev->input)->type) ||
+ (CX23885_VMUX_CABLE == INPUT(dev->input)->type))
+ i->index = 2;
+ else
+ i->index = dev->audinput;
dprintk(1, "%s(input=%d)\n", __func__, i->index);
return cx23885_query_audinput(file, priv, i);
@@ -1431,8 +822,13 @@ static int vidioc_g_audinput(struct file *file, void *priv,
static int vidioc_s_audinput(struct file *file, void *priv,
const struct v4l2_audio *i)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- if (i->index >= 2)
+ struct cx23885_dev *dev = video_drvdata(file);
+
+ if ((CX23885_VMUX_TELEVISION == INPUT(dev->input)->type) ||
+ (CX23885_VMUX_CABLE == INPUT(dev->input)->type)) {
+ return i->index != 2 ? -EINVAL : 0;
+ }
+ if (i->index > 1)
return -EINVAL;
dprintk(1, "%s(%d)\n", __func__, i->index);
@@ -1445,35 +841,10 @@ static int vidioc_s_audinput(struct file *file, void *priv,
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;
+ struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@@ -1489,7 +860,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *t)
{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@@ -1504,14 +875,12 @@ static int vidioc_s_tuner(struct file *file, void *priv,
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;
+ struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
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->type = V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
call_all(dev, tuner, g_frequency, f);
@@ -1521,20 +890,23 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency *f)
{
- struct v4l2_control ctrl;
+ struct v4l2_ctrl *mute;
+ int old_mute_val = 1;
if (dev->tuner_type == TUNER_ABSENT)
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);
+ mute = v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_AUDIO_MUTE);
+ if (mute) {
+ old_mute_val = v4l2_ctrl_g_ctrl(mute);
+ if (!old_mute_val)
+ v4l2_ctrl_s_ctrl(mute, 1);
+ }
call_all(dev, tuner, s_frequency, f);
@@ -1542,10 +914,8 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
msleep(100);
/* I need to unmute audio here */
- ctrl.value = 0;
- cx23885_set_control(dev, &ctrl);
-
- mutex_unlock(&dev->lock);
+ if (old_mute_val == 0)
+ v4l2_ctrl_s_ctrl(mute, old_mute_val);
return 0;
}
@@ -1553,8 +923,9 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
const struct v4l2_frequency *f)
{
- struct v4l2_control ctrl;
- struct videobuf_dvb_frontend *vfe;
+ struct v4l2_ctrl *mute;
+ int old_mute_val = 1;
+ struct vb2_dvb_frontend *vfe;
struct dvb_frontend *fe;
struct analog_parameters params = {
@@ -1564,21 +935,22 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
.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);
+ mute = v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_AUDIO_MUTE);
+ if (mute) {
+ old_mute_val = v4l2_ctrl_g_ctrl(mute);
+ if (!old_mute_val)
+ v4l2_ctrl_s_ctrl(mute, 1);
+ }
/* 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);
+ vfe = vb2_dvb_get_frontend(&dev->ts2.frontends, 1);
if (!vfe) {
- mutex_unlock(&dev->lock);
return -EINVAL;
}
@@ -1600,10 +972,8 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
msleep(100);
/* I need to unmute audio here */
- ctrl.value = 0;
- cx23885_set_control(dev, &ctrl);
-
- mutex_unlock(&dev->lock);
+ if (old_mute_val == 0)
+ v4l2_ctrl_s_ctrl(mute, old_mute_val);
return 0;
}
@@ -1611,8 +981,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
int cx23885_set_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
+ struct cx23885_dev *dev = video_drvdata(file);
int ret;
switch (dev->board) {
@@ -1636,28 +1005,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
/* ----------------------------------------------------------- */
-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;
@@ -1702,13 +1049,6 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
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);
@@ -1721,12 +1061,12 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
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,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
};
static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1738,21 +1078,19 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.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_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .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_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_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,
@@ -1765,6 +1103,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_enumaudio = vidioc_enum_audinput,
.vidioc_g_audio = vidioc_g_audinput,
.vidioc_s_audio = vidioc_s_audinput,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
static struct video_device cx23885_vbi_template;
@@ -1775,14 +1115,6 @@ static struct video_device cx23885_video_template = {
.tvnorms = CX23885_NORMS,
};
-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__);
@@ -1794,7 +1126,6 @@ void cx23885_video_unregister(struct cx23885_dev *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))
@@ -1802,8 +1133,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
else
video_device_release(dev->video_dev);
dev->video_dev = NULL;
-
- btcx_riscmem_free(dev->pci, &dev->vidq.stopper);
}
if (dev->audio_dev)
@@ -1812,6 +1141,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
int cx23885_video_register(struct cx23885_dev *dev)
{
+ struct vb2_queue *q;
int err;
dprintk(1, "%s()\n", __func__);
@@ -1822,24 +1152,16 @@ int cx23885_video_register(struct cx23885_dev *dev)
strcpy(cx23885_vbi_template.name, "cx23885-vbi");
dev->tvnorm = V4L2_STD_NTSC_M;
+ dev->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
+ dev->field = V4L2_FIELD_INTERLACED;
+ dev->width = 720;
+ dev->height = norm_maxh(dev->tvnorm);
/* 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);
@@ -1893,9 +1215,49 @@ int cx23885_video_register(struct cx23885_dev *dev)
}
}
+ /* initial device configuration */
+ mutex_lock(&dev->lock);
+ cx23885_set_tvnorm(dev, dev->tvnorm);
+ cx23885_video_mux(dev, 0);
+ cx23885_audio_mux(dev, 0);
+ mutex_unlock(&dev->lock);
+
+ q = &dev->vb2_vidq;
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+ q->gfp_flags = GFP_DMA32;
+ q->min_buffers_needed = 2;
+ q->drv_priv = dev;
+ q->buf_struct_size = sizeof(struct cx23885_buffer);
+ q->ops = &cx23885_video_qops;
+ q->mem_ops = &vb2_dma_sg_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &dev->lock;
+
+ err = vb2_queue_init(q);
+ if (err < 0)
+ goto fail_unreg;
+
+ q = &dev->vb2_vbiq;
+ q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+ q->gfp_flags = GFP_DMA32;
+ q->min_buffers_needed = 2;
+ q->drv_priv = dev;
+ q->buf_struct_size = sizeof(struct cx23885_buffer);
+ q->ops = &cx23885_vbi_qops;
+ q->mem_ops = &vb2_dma_sg_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &dev->lock;
+
+ err = vb2_queue_init(q);
+ if (err < 0)
+ goto fail_unreg;
+
/* register Video device */
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
&cx23885_video_template, "video");
+ dev->video_dev->queue = &dev->vb2_vidq;
err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
video_nr[dev->nr]);
if (err < 0) {
@@ -1909,6 +1271,7 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* register VBI device */
dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
&cx23885_vbi_template, "vbi");
+ dev->vbi_dev->queue = &dev->vb2_vbiq;
err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->nr]);
if (err < 0) {
@@ -1922,18 +1285,9 @@ int cx23885_video_register(struct cx23885_dev *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/pci/cx23885/cx23885-video.h b/drivers/media/pci/cx23885/cx23885-video.h
index c961a2b..291e8f3 100644
--- a/drivers/media/pci/cx23885/cx23885-video.h
+++ b/drivers/media/pci/cx23885/cx23885-video.h
@@ -12,11 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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_VIDEO_H_
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 0e086c0..6c35e61 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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>
@@ -25,19 +21,20 @@
#include <linux/slab.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ctrls.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
+#include <media/videobuf2-dma-sg.h>
+#include <media/videobuf2-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 CX23885_VERSION "0.0.4"
#define UNSET (-1U)
@@ -46,9 +43,6 @@
/* 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 */
@@ -98,6 +92,7 @@
#define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42
#define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE 43
#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44
+#define CX23885_BOARD_DVBSKY_T9580 45
#define GPIO_0 0x00000001
#define GPIO_1 0x00000002
@@ -131,14 +126,6 @@ struct cx23885_fmt {
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;
@@ -146,30 +133,6 @@ struct cx23885_tvnorm {
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,
@@ -189,14 +152,22 @@ enum cx23885_src_sel_type {
CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO
};
+struct cx23885_riscmem {
+ unsigned int size;
+ __le32 *cpu;
+ __le32 *jmp;
+ dma_addr_t dma;
+};
+
/* buffer for one video frame */
struct cx23885_buffer {
/* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
+ struct vb2_buffer vb;
+ struct list_head queue;
/* cx23885 specific */
unsigned int bpl;
- struct btcx_riscmem risc;
+ struct cx23885_riscmem risc;
struct cx23885_fmt *fmt;
u32 count;
};
@@ -268,9 +239,6 @@ struct cx23885_i2c {
struct cx23885_dmaqueue {
struct list_head active;
- struct list_head queued;
- struct timer_list timeout;
- struct btcx_riscmem stopper;
u32 count;
};
@@ -280,7 +248,7 @@ struct cx23885_tsport {
int nr;
int sram_chno;
- struct videobuf_dvb_frontends frontends;
+ struct vb2_dvb_frontends frontends;
/* dma queues */
struct cx23885_dmaqueue mpegq;
@@ -326,7 +294,12 @@ struct cx23885_tsport {
/* Workaround for a temp dvb_frontend that the tuner can attached to */
struct dvb_frontend analog_fe;
+ struct i2c_client *i2c_client_demod;
+ struct i2c_client *i2c_client_tuner;
+
int (*set_frontend)(struct dvb_frontend *fe);
+ int (*fe_set_voltage)(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage);
};
struct cx23885_kernel_ir {
@@ -339,8 +312,11 @@ struct cx23885_kernel_ir {
struct cx23885_audio_buffer {
unsigned int bpl;
- struct btcx_riscmem risc;
- struct videobuf_dmabuf dma;
+ struct cx23885_riscmem risc;
+ void *vaddr;
+ struct scatterlist *sglist;
+ int sglen;
+ int nr_pages;
};
struct cx23885_audio_dev {
@@ -358,8 +334,6 @@ struct cx23885_audio_dev {
unsigned int period_size;
unsigned int num_periods;
- struct videobuf_dmabuf *dma_risc;
-
struct cx23885_audio_buffer *buf;
struct snd_pcm_substream *substream;
@@ -368,6 +342,7 @@ struct cx23885_audio_dev {
struct cx23885_dev {
atomic_t refcount;
struct v4l2_device v4l2_dev;
+ struct v4l2_ctrl_handler ctrl_handler;
/* pci stuff */
struct pci_dev *pci;
@@ -407,7 +382,6 @@ struct cx23885_dev {
} bridge;
/* Analog video */
- u32 resources;
unsigned int input;
unsigned int audinput; /* Selectable audio input */
u32 tvaudio;
@@ -417,7 +391,6 @@ struct cx23885_dev {
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;
@@ -435,17 +408,24 @@ struct cx23885_dev {
u32 freq;
struct video_device *video_dev;
struct video_device *vbi_dev;
- struct video_device *radio_dev;
+
+ /* video capture */
+ struct cx23885_fmt *fmt;
+ unsigned int width, height;
+ unsigned field;
struct cx23885_dmaqueue vidq;
+ struct vb2_queue vb2_vidq;
struct cx23885_dmaqueue vbiq;
+ struct vb2_queue vb2_vbiq;
+
spinlock_t slock;
/* MPEG Encoder ONLY settings */
u32 cx23417_mailbox;
- struct cx2341x_mpeg_params mpeg_params;
+ struct cx2341x_handler cxhdl;
struct video_device *v4l_device;
- atomic_t v4l_reader_count;
+ struct vb2_queue vb2_mpegq;
struct cx23885_tvnorm encodernorm;
/* Analog raw audio */
@@ -521,26 +501,21 @@ extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
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,
+extern int cx23885_risc_buffer(struct pci_dev *pci, struct cx23885_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,
+ struct cx23885_riscmem *risc, struct scatterlist *sglist,
unsigned int top_offset, unsigned int bottom_offset,
unsigned int bpl, unsigned int padding, unsigned int lines);
+int cx23885_start_dma(struct cx23885_tsport *port,
+ struct cx23885_dmaqueue *q,
+ struct cx23885_buffer *buf);
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);
@@ -574,13 +549,11 @@ 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 int cx23885_buf_prepare(struct cx23885_buffer *buf,
+ struct cx23885_tsport *port);
extern void cx23885_buf_queue(struct cx23885_tsport *port,
struct cx23885_buffer *buf);
-extern void cx23885_free_buffer(struct videobuf_queue *q,
+extern void cx23885_free_buffer(struct cx23885_dev *dev,
struct cx23885_buffer *buf);
/* ----------------------------------------------------------- */
@@ -595,8 +568,6 @@ 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, const 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);
/* ----------------------------------------------------------- */
@@ -604,9 +575,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
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 struct vb2_ops cx23885_vbi_qops;
extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status);
/* cx23885-i2c.c */
@@ -638,7 +607,7 @@ extern struct cx23885_audio_dev *cx23885_audio_register(
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 cx23885_riscmem *risc,
struct scatterlist *sglist,
unsigned int bpl,
unsigned int lines,
@@ -649,15 +618,10 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
static inline unsigned int norm_maxw(v4l2_std_id norm)
{
- return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
+ return (norm & V4L2_STD_525_60) ? 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;
+ return (norm & V4L2_STD_525_60) ? 480 : 576;
}
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index 2c951de..c1aa888 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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>
@@ -263,7 +258,7 @@ static inline unsigned int lpf_count_to_us(unsigned int count)
}
/*
- * FIFO register pulse width count compuations
+ * FIFO register pulse width count computations
*/
static u32 clock_divider_to_resolution(u16 divider)
{
diff --git a/drivers/media/pci/cx23885/cx23888-ir.h b/drivers/media/pci/cx23885/cx23888-ir.h
index d2de41c..ff74a93 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.h
+++ b/drivers/media/pci/cx23885/cx23888-ir.h
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You 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_
diff --git a/drivers/media/pci/cx23885/netup-eeprom.c b/drivers/media/pci/cx23885/netup-eeprom.c
index 98a48f5..b6542ee 100644
--- a/drivers/media/pci/cx23885/netup-eeprom.c
+++ b/drivers/media/pci/cx23885/netup-eeprom.c
@@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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.
*/
#
diff --git a/drivers/media/pci/cx23885/netup-eeprom.h b/drivers/media/pci/cx23885/netup-eeprom.h
index 13926e1..90cac5b 100644
--- a/drivers/media/pci/cx23885/netup-eeprom.h
+++ b/drivers/media/pci/cx23885/netup-eeprom.h
@@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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
diff --git a/drivers/media/pci/cx23885/netup-init.c b/drivers/media/pci/cx23885/netup-init.c
index 0044fef..76d9487 100644
--- a/drivers/media/pci/cx23885/netup-init.c
+++ b/drivers/media/pci/cx23885/netup-init.c
@@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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"
diff --git a/drivers/media/pci/cx23885/netup-init.h b/drivers/media/pci/cx23885/netup-init.h
index d26ae4b..daaa212 100644
--- a/drivers/media/pci/cx23885/netup-init.h
+++ b/drivers/media/pci/cx23885/netup-init.h
@@ -17,9 +17,5 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You 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/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c
index 1f43be0..a664997 100644
--- a/drivers/media/pci/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c
@@ -330,8 +330,9 @@ int cx25821_write_frame(struct cx25821_channel *chan,
if (frame_size - curpos < count)
count = frame_size - curpos;
- memcpy((char *)out->_data_buf_virt_addr + frame_offset + curpos,
- data, count);
+ if (copy_from_user((__force char *)out->_data_buf_virt_addr + frame_offset + curpos,
+ data, count))
+ return -EFAULT;
curpos += count;
if (curpos == frame_size) {
out->_frame_count++;
diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
index e18a7ac..851754b 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -78,19 +78,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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",
@@ -99,23 +99,23 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -127,13 +127,13 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- },{
+ }, {
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
- }},
+ } },
},
[CX88_BOARD_PIXELVIEW] = {
.name = "PixelView",
@@ -141,17 +141,17 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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,
@@ -164,19 +164,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
- .input = {{
+ .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",
@@ -185,28 +185,28 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -222,19 +222,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -249,25 +249,25 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
- .input = {{
+ .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,
@@ -283,14 +283,14 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0035e700,
.gpio1 = 0x00003004,
.gpio2 = 0x0035e700,
.gpio3 = 0x02000000,
- },{
+ }, {
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -298,14 +298,14 @@ static const struct cx88_board cx88_boards[] = {
.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,
@@ -322,22 +322,22 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -351,16 +351,16 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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",
@@ -369,19 +369,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -394,16 +394,16 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -417,22 +417,22 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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",
@@ -440,17 +440,17 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -459,15 +459,15 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -476,23 +476,23 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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,
@@ -521,23 +521,23 @@ static const struct cx88_board cx88_boards[] = {
0 - normal RF
1 - high RF
*/
- .input = {{
+ .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] = {
@@ -546,10 +546,10 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
- }},
+ } },
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_CONEXANT_DVB_T1] = {
@@ -558,10 +558,10 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
- }},
+ } },
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_PROVIDEO_PV259] = {
@@ -570,11 +570,11 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.audioroute = 1,
- }},
+ } },
.mpeg = CX88_MPEG_BLACKBIRD,
},
[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
@@ -583,15 +583,15 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -600,17 +600,17 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -632,19 +632,19 @@ static const struct cx88_board cx88_boards[] = {
*
* GPIO[16] = Remote control input
*/
- .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,
@@ -659,25 +659,25 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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,
@@ -692,22 +692,22 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -722,19 +722,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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)",
@@ -745,19 +745,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_addr = ADDR_UNSET,
/* Some variants use a tda9874 and so need the tvaudio module. */
.audio_chip = CX88_AUDIO_TVAUDIO,
- .input = {{
+ .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,
@@ -770,19 +770,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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] = {
@@ -791,32 +791,32 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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 = {{
+ .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] = {
@@ -826,19 +826,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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] = {
@@ -848,22 +848,22 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -876,21 +876,21 @@ static const struct cx88_board cx88_boards[] = {
/* Alexander Wold <awold@bigfoot.com> */
.name = "Kworld V-Stream Xpert DVD",
.tuner_type = UNSET,
- .input = {{
+ .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",
@@ -898,28 +898,28 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -928,16 +928,16 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -947,28 +947,28 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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",
@@ -978,22 +978,22 @@ static const struct cx88_board cx88_boards[] = {
.radio_addr = ADDR_UNSET,
.audio_chip = CX88_AUDIO_WM8775,
.i2sinputcntl = 2,
- .input = {{
+ .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] = {
@@ -1002,10 +1002,10 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
- }},
+ } },
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_KWORLD_DVBS_100] = {
@@ -1015,22 +1015,22 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.audio_chip = CX88_AUDIO_WM8775,
- .input = {{
+ .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] = {
@@ -1040,16 +1040,16 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
},
@@ -1060,13 +1060,13 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- },{
+ }, {
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- }},
+ } },
/* fixme: Add radio support */
.mpeg = CX88_MPEG_DVB,
},
@@ -1078,19 +1078,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
TDA9887_PORT2_ACTIVE,
- .input = {{
+ .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,
@@ -1106,17 +1106,17 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -1125,15 +1125,15 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -1142,22 +1142,22 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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,
@@ -1171,19 +1171,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -1193,19 +1193,19 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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] = {
@@ -1217,11 +1217,11 @@ static const struct cx88_board cx88_boards[] = {
.tda9887_conf = TDA9887_PRESENT,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0000BDE6
- }},
+ } },
.mpeg = CX88_MPEG_BLACKBIRD,
},
[CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = {
@@ -1233,11 +1233,11 @@ static const struct cx88_board cx88_boards[] = {
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
TDA9887_PORT2_ACTIVE,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x5da6,
- }},
+ } },
.mpeg = CX88_MPEG_BLACKBIRD,
},
[CX88_BOARD_NPGTECH_REALTV_TOP10FM] = {
@@ -1246,19 +1246,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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,
@@ -1271,7 +1271,7 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x00017304,
@@ -1299,7 +1299,7 @@ static const struct cx88_board cx88_boards[] = {
.gpio1 = 0x0000b207,
.gpio2 = 0x0001d701,
.gpio3 = 0x02000000,
- }},
+ } },
.radio = {
.type = CX88_RADIO,
.gpio0 = 0x00015702,
@@ -1316,35 +1316,35 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
+ .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,
@@ -1360,13 +1360,13 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
- },{
+ }, {
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- }},
+ } },
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_HAUPPAUGE_HVR3000] = {
@@ -1377,25 +1377,25 @@ static const struct cx88_board cx88_boards[] = {
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.audio_chip = CX88_AUDIO_WM8775,
- .input = {{
+ .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,
@@ -1411,19 +1411,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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",
@@ -1431,28 +1431,28 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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",
@@ -1465,25 +1465,25 @@ static const struct cx88_board cx88_boards[] = {
/*
* gpio0 as reported by Mike Crash <mike AT mikecrash.com>
*/
- .input = {{
+ .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,
@@ -1510,19 +1510,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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",
@@ -1530,24 +1530,24 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -1557,7 +1557,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x000027df, /* Unconfirmed */
@@ -1815,19 +1815,19 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .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] = {
@@ -1967,7 +1967,7 @@ static const struct cx88_board cx88_boards[] = {
* 3: Line-In Expansion
* 4: FM Stereo
*/
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0xc4bf,
@@ -2001,7 +2001,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2013,7 +2013,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2025,7 +2025,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2037,7 +2037,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2049,7 +2049,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2061,7 +2061,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2073,7 +2073,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
.gpio0 = 0x8080,
@@ -2086,7 +2086,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2098,7 +2098,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2110,7 +2110,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2170,7 +2170,7 @@ static const struct cx88_board cx88_boards[] = {
* 13: audio source (0=tuner audio,1=line in)
* 14: FM (0=on,1=off ???)
*/
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0400, /* pin 2 = 0 */
@@ -2211,7 +2211,7 @@ static const struct cx88_board cx88_boards[] = {
* 13: audio source (0=tuner audio,1=line in)
* 14: FM (0=on,1=off ???)
*/
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0400, /* pin 2 = 0 */
@@ -2229,7 +2229,7 @@ static const struct cx88_board cx88_boards[] = {
.gpio0 = 0x0400, /* pin 2 = 0 */
.gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
.gpio2 = 0x0000,
- }},
+ } },
.radio = {
.type = CX88_RADIO,
.gpio0 = 0x0400, /* pin 2 = 0 */
@@ -2252,7 +2252,7 @@ static const struct cx88_board cx88_boards[] = {
* 14: 0: FM radio
* 16: 0: RF input is cable
*/
- .input = {{
+ .input = { {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0403,
@@ -2280,7 +2280,7 @@ static const struct cx88_board cx88_boards[] = {
.gpio1 = 0xF0F7,
.gpio2 = 0x0101,
.gpio3 = 0x0000,
- }},
+ } },
.radio = {
.type = CX88_RADIO,
.gpio0 = 0x0403,
@@ -2308,7 +2308,7 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
@@ -2324,19 +2324,19 @@ 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,
@@ -2348,176 +2348,176 @@ static const struct cx88_subid cx88_subids[] = {
.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,
@@ -2530,55 +2530,55 @@ static const struct cx88_subid cx88_subids[] = {
.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,
@@ -2590,60 +2590,60 @@ static const struct cx88_subid cx88_subids[] = {
.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,
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index ed8cb90..ce27e6d 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -696,7 +696,6 @@ static struct videobuf_queue *get_queue(struct file *file)
return &fh->vbiq;
default:
BUG();
- return NULL;
}
}
@@ -711,7 +710,6 @@ static int get_resource(struct file *file)
return RESOURCE_VBI;
default:
BUG();
- return 0;
}
}
@@ -812,7 +810,6 @@ video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
file->f_flags & O_NONBLOCK);
default:
BUG();
- return 0;
}
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index da8f848..c82e855 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -149,7 +149,7 @@ static u32 ddb_i2c_functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-struct i2c_algorithm ddb_i2c_algo = {
+static struct i2c_algorithm ddb_i2c_algo = {
.master_xfer = ddb_i2c_master_xfer,
.functionality = ddb_i2c_functionality,
};
@@ -266,7 +266,7 @@ static void io_free(struct pci_dev *pdev, u8 **vbuf,
for (i = 0; i < num; i++) {
if (vbuf[i]) {
pci_free_consistent(pdev, size, vbuf[i], pbuf[i]);
- vbuf[i] = 0;
+ vbuf[i] = NULL;
}
}
}
@@ -440,7 +440,7 @@ static u32 ddb_output_free(struct ddb_output *output)
}
static ssize_t ddb_output_write(struct ddb_output *output,
- const u8 *buf, size_t count)
+ const __user u8 *buf, size_t count)
{
struct ddb *dev = output->port->dev;
u32 idx, off, stat = output->stat;
@@ -506,7 +506,7 @@ static u32 ddb_input_avail(struct ddb_input *input)
return 0;
}
-static ssize_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count)
+static ssize_t ddb_input_read(struct ddb_input *input, __user u8 *buf, size_t count)
{
struct ddb *dev = input->port->dev;
u32 left = count;
@@ -849,7 +849,7 @@ static int dvb_input_attach(struct ddb_input *input)
return ret;
input->attached = 4;
- input->fe = 0;
+ input->fe = NULL;
switch (port->type) {
case DDB_TUNER_DVBS_ST:
if (demod_attach_stv0900(input, 0) < 0)
@@ -895,7 +895,7 @@ static int dvb_input_attach(struct ddb_input *input)
/****************************************************************************/
/****************************************************************************/
-static ssize_t ts_write(struct file *file, const char *buf,
+static ssize_t ts_write(struct file *file, const __user char *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev = file->private_data;
@@ -920,7 +920,7 @@ static ssize_t ts_write(struct file *file, const char *buf,
return (left == count) ? -EAGAIN : (count - left);
}
-static ssize_t ts_read(struct file *file, char *buf,
+static ssize_t ts_read(struct file *file, __user char *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev = file->private_data;
@@ -975,11 +975,9 @@ static const struct file_operations ci_fops = {
.open = dvb_generic_open,
.release = dvb_generic_release,
.poll = ts_poll,
- .mmap = 0,
};
static struct dvb_device dvbdev_ci = {
- .priv = 0,
.readers = -1,
.writers = -1,
.users = -1,
@@ -1038,7 +1036,7 @@ static void output_tasklet(unsigned long data)
}
-struct cxd2099_cfg cxd_cfg = {
+static struct cxd2099_cfg cxd_cfg = {
.bitrate = 62000,
.adr = 0x40,
.polarity = 1,
@@ -1127,7 +1125,7 @@ static void ddb_ports_detach(struct ddb *dev)
ddb_output_stop(port->output);
dvb_ca_en50221_release(port->en);
kfree(port->en);
- port->en = 0;
+ port->en = NULL;
dvb_unregister_adapter(&port->output->adap);
}
break;
@@ -1413,9 +1411,9 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
#define DDB_MAGIC 'd'
struct ddb_flashio {
- __u8 *write_buf;
+ __user __u8 *write_buf;
__u32 write_len;
- __u8 *read_buf;
+ __user __u8 *read_buf;
__u32 read_len;
};
@@ -1439,7 +1437,7 @@ static int ddb_open(struct inode *inode, struct file *file)
static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct ddb *dev = file->private_data;
- void *parg = (void *)arg;
+ __user void *parg = (__user void *)arg;
int res;
switch (cmd) {
@@ -1558,7 +1556,7 @@ static void ddb_remove(struct pci_dev *pdev)
ddb_device_destroy(dev);
ddb_unmap(dev);
- pci_set_drvdata(pdev, 0);
+ pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
}
@@ -1637,7 +1635,7 @@ fail1:
fail:
printk(KERN_ERR "fail\n");
ddb_unmap(dev);
- pci_set_drvdata(pdev, 0);
+ pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
return -1;
}
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
index 8b1b41d..be87fbd 100644
--- a/drivers/media/pci/ddbridge/ddbridge.h
+++ b/drivers/media/pci/ddbridge/ddbridge.h
@@ -156,7 +156,7 @@ struct ddb_port {
struct ddb {
struct pci_dev *pdev;
- unsigned char *regs;
+ unsigned char __iomem *regs;
struct ddb_port port[DDB_MAX_PORT];
struct ddb_i2c i2c[DDB_MAX_I2C];
struct ddb_input input[DDB_MAX_INPUT];
@@ -173,12 +173,10 @@ struct ddb {
/****************************************************************************/
#define ddbwritel(_val, _adr) writel((_val), \
- (char *) (dev->regs+(_adr)))
-#define ddbreadl(_adr) readl((char *) (dev->regs+(_adr)))
-#define ddbcpyto(_adr, _src, _count) memcpy_toio((char *) \
- (dev->regs+(_adr)), (_src), (_count))
-#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), (char *) \
- (dev->regs+(_adr)), (_count))
+ dev->regs+(_adr))
+#define ddbreadl(_adr) readl(dev->regs+(_adr))
+#define ddbcpyto(_adr, _src, _count) memcpy_toio(dev->regs+(_adr), (_src), (_count))
+#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), dev->regs+(_adr), (_count))
/****************************************************************************/
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index e8826c5..ed11716 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -614,7 +614,7 @@ static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
static void dm1105_set_dma_addr(struct dm1105_dev *dev)
{
- dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr));
+ dm_writel(DM1105_STADR, (__force u32)cpu_to_le32(dev->dma_addr));
}
static int dm1105_dma_map(struct dm1105_dev *dev)
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
index 7a9b98b..7bf9cbc 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
@@ -81,7 +81,7 @@ static void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *itvsc,
int period_elapsed = 0;
int length;
- dprintk("ivtv alsa announce ptr=%p data=%p num_bytes=%zd\n", itvsc,
+ dprintk("ivtv alsa announce ptr=%p data=%p num_bytes=%zu\n", itvsc,
pcm_data, num_bytes);
substream = itvsc->capture_pcm_substream;
diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c
index ed73edd..4b0e758 100644
--- a/drivers/media/pci/ivtv/ivtv-firmware.c
+++ b/drivers/media/pci/ivtv/ivtv-firmware.c
@@ -65,7 +65,7 @@ retry:
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);
+ IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zu)\n", fn, size, fw->size);
release_firmware(fw);
retries--;
goto retry;
@@ -76,7 +76,7 @@ retry:
dst++;
src++;
}
- IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size);
+ IVTV_INFO("Loaded %s firmware (%zu bytes)\n", fn, fw->size);
release_firmware(fw);
return size;
}
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c
index 19a7c9b..ab6d5d2 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -192,11 +192,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
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);
+ write_dec_sync(DMA_MAGIC_COOKIE, offset - IVTV_DECODER_OFFSET);
}
else {
s->pending_backup = read_enc(offset);
- write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
+ write_enc_sync(DMA_MAGIC_COOKIE, offset);
}
s->pending_offset = offset;
}
@@ -275,13 +275,11 @@ static void dma_post(struct ivtv_stream *s)
if (x == 0 && ivtv_use_dma(s)) {
offset = s->dma_last_offset;
- if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
+ if (le32_to_cpu(u32buf[offset / 4]) != DMA_MAGIC_COOKIE)
{
- for (offset = 0; offset < 64; offset++) {
- if (u32buf[offset] == DMA_MAGIC_COOKIE) {
+ for (offset = 0; offset < 64; offset++)
+ if (le32_to_cpu(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);
diff --git a/drivers/media/pci/mantis/hopper_vp3028.c b/drivers/media/pci/mantis/hopper_vp3028.c
index 68a29f8..1032db6 100644
--- a/drivers/media/pci/mantis/hopper_vp3028.c
+++ b/drivers/media/pci/mantis/hopper_vp3028.c
@@ -34,7 +34,7 @@
#include "mantis_dvb.h"
#include "hopper_vp3028.h"
-struct zl10353_config hopper_vp3028_config = {
+static struct zl10353_config hopper_vp3028_config = {
.demod_address = 0x0f,
};
diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h
index f2410cf..8ff448b 100644
--- a/drivers/media/pci/mantis/mantis_common.h
+++ b/drivers/media/pci/mantis/mantis_common.h
@@ -127,7 +127,7 @@ struct mantis_pci {
u32 last_block;
u8 *buf_cpu;
dma_addr_t buf_dma;
- u32 *risc_cpu;
+ __le32 *risc_cpu;
dma_addr_t risc_dma;
struct tasklet_struct tasklet;
diff --git a/drivers/media/pci/mantis/mantis_vp1033.c b/drivers/media/pci/mantis/mantis_vp1033.c
index 115003e8..12a6adb 100644
--- a/drivers/media/pci/mantis/mantis_vp1033.c
+++ b/drivers/media/pci/mantis/mantis_vp1033.c
@@ -35,7 +35,7 @@
#include "mantis_vp1033.h"
#include "mantis_reg.h"
-u8 lgtdqcs001f_inittab[] = {
+static u8 lgtdqcs001f_inittab[] = {
0x01, 0x15,
0x02, 0x30,
0x03, 0x00,
@@ -150,7 +150,7 @@ static int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
return 0;
}
-struct stv0299_config lgtdqcs001f_config = {
+static struct stv0299_config lgtdqcs001f_config = {
.demod_address = 0x68,
.inittab = lgtdqcs001f_inittab,
.mclk = 88000000UL,
diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c
index 430ae84..7c1bd16 100644
--- a/drivers/media/pci/mantis/mantis_vp1034.c
+++ b/drivers/media/pci/mantis/mantis_vp1034.c
@@ -36,7 +36,7 @@
#include "mantis_vp1034.h"
#include "mantis_reg.h"
-struct mb86a16_config vp1034_mb86a16_config = {
+static struct mb86a16_config vp1034_mb86a16_config = {
.demod_address = 0x08,
.set_voltage = vp1034_set_voltage,
};
diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
index 07a2074..7082fcb 100644
--- a/drivers/media/pci/mantis/mantis_vp1041.c
+++ b/drivers/media/pci/mantis/mantis_vp1041.c
@@ -263,7 +263,7 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
{ 0xffff , 0xff },
};
-struct stb0899_config vp1041_stb0899_config = {
+static struct stb0899_config vp1041_stb0899_config = {
.init_dev = vp1041_stb0899_s1_init_1,
.init_s2_demod = stb0899_s2_init_2,
.init_s1_demod = vp1041_stb0899_s1_init_3,
@@ -300,7 +300,7 @@ struct stb0899_config vp1041_stb0899_config = {
.tuner_set_rfsiggain = NULL,
};
-struct stb6100_config vp1041_stb6100_config = {
+static struct stb6100_config vp1041_stb6100_config = {
.tuner_address = 0x60,
.refclock = 27000000,
};
diff --git a/drivers/media/pci/mantis/mantis_vp2033.c b/drivers/media/pci/mantis/mantis_vp2033.c
index 1ca6837..8d48b5a 100644
--- a/drivers/media/pci/mantis/mantis_vp2033.c
+++ b/drivers/media/pci/mantis/mantis_vp2033.c
@@ -37,12 +37,12 @@
#define MANTIS_MODEL_NAME "VP-2033"
#define MANTIS_DEV_TYPE "DVB-C"
-struct tda1002x_config vp2033_tda1002x_cu1216_config = {
+static struct tda1002x_config vp2033_tda1002x_cu1216_config = {
.demod_address = 0x18 >> 1,
.invert = 1,
};
-struct tda10023_config vp2033_tda10023_cu1216_config = {
+static struct tda10023_config vp2033_tda10023_cu1216_config = {
.demod_address = 0x18 >> 1,
.invert = 1,
};
diff --git a/drivers/media/pci/mantis/mantis_vp2040.c b/drivers/media/pci/mantis/mantis_vp2040.c
index d480741..8dd17d7 100644
--- a/drivers/media/pci/mantis/mantis_vp2040.c
+++ b/drivers/media/pci/mantis/mantis_vp2040.c
@@ -37,12 +37,12 @@
#define MANTIS_MODEL_NAME "VP-2040"
#define MANTIS_DEV_TYPE "DVB-C"
-struct tda1002x_config vp2040_tda1002x_cu1216_config = {
+static struct tda1002x_config vp2040_tda1002x_cu1216_config = {
.demod_address = 0x18 >> 1,
.invert = 1,
};
-struct tda10023_config vp2040_tda10023_cu1216_config = {
+static struct tda10023_config vp2040_tda10023_cu1216_config = {
.demod_address = 0x18 >> 1,
.invert = 1,
};
diff --git a/drivers/media/pci/mantis/mantis_vp3030.c b/drivers/media/pci/mantis/mantis_vp3030.c
index c09308cd..5c1dd92 100644
--- a/drivers/media/pci/mantis/mantis_vp3030.c
+++ b/drivers/media/pci/mantis/mantis_vp3030.c
@@ -35,11 +35,11 @@
#include "mantis_dvb.h"
#include "mantis_vp3030.h"
-struct zl10353_config mantis_vp3030_config = {
+static struct zl10353_config mantis_vp3030_config = {
.demod_address = 0x0f,
};
-struct tda665x_config env57h12d5_config = {
+static struct tda665x_config env57h12d5_config = {
.name = "ENV57H12D5 (ET-50DT)",
.addr = 0x60,
.frequency_min = 47000000,
diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c
index 9e82d21..039bed3 100644
--- a/drivers/media/pci/ngene/ngene-cards.c
+++ b/drivers/media/pci/ngene/ngene-cards.c
@@ -696,7 +696,7 @@ static struct ngene_info ngene_info_m780 = {
.demod_attach = { NULL, demod_attach_lg330x },
/* Ensure these are NULL else the frame will call them (as funcs) */
- .tuner_attach = { 0, 0, 0, 0 },
+ .tuner_attach = { NULL, NULL, NULL, NULL },
.fe_config = { NULL, &aver_m780 },
.avf = { 0 },
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
index 4930b55..e29bc3af4 100644
--- a/drivers/media/pci/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -57,15 +57,13 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define dprintk if (debug) printk
-#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
-#define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr)))
-#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
+#define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr))
+#define ngwritel(dat, adr) writel((dat), dev->iomem + (adr))
+#define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr))
#define ngreadl(adr) readl(dev->iomem + (adr))
#define ngreadb(adr) readb(dev->iomem + (adr))
-#define ngcpyto(adr, src, count) memcpy_toio((char *) \
- (dev->iomem + (adr)), (src), (count))
-#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \
- (dev->iomem + (adr)), (count))
+#define ngcpyto(adr, src, count) memcpy_toio(dev->iomem + (adr), (src), (count))
+#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), dev->iomem + (adr), (count))
/****************************************************************************/
/* nGene interrupt handler **************************************************/
@@ -1592,7 +1590,7 @@ static void cxd_detach(struct ngene *dev)
dvb_ca_en50221_release(ci->en);
kfree(ci->en);
- ci->en = 0;
+ ci->en = NULL;
}
/***********************************/
diff --git a/drivers/media/pci/ngene/ngene-dvb.c b/drivers/media/pci/ngene/ngene-dvb.c
index fcb16a6..59bb285 100644
--- a/drivers/media/pci/ngene/ngene-dvb.c
+++ b/drivers/media/pci/ngene/ngene-dvb.c
@@ -47,7 +47,7 @@
/* COMMAND API interface ****************************************************/
/****************************************************************************/
-static ssize_t ts_write(struct file *file, const char *buf,
+static ssize_t ts_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev = file->private_data;
@@ -59,12 +59,12 @@ static ssize_t ts_write(struct file *file, const char *buf,
(&dev->tsout_rbuf) >= count) < 0)
return 0;
- dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);
+ dvb_ringbuffer_write_user(&dev->tsout_rbuf, buf, count);
return count;
}
-static ssize_t ts_read(struct file *file, char *buf,
+static ssize_t ts_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev = file->private_data;
@@ -97,7 +97,6 @@ static const struct file_operations ci_fops = {
};
struct dvb_device ngene_dvbdev_ci = {
- .priv = 0,
.readers = -1,
.writers = -1,
.users = -1,
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index 22c39ff..51e2fbd 100644
--- a/drivers/media/pci/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
@@ -737,7 +737,7 @@ typedef void (tx_cb_t)(struct ngene *, u32);
struct ngene {
int nr;
struct pci_dev *pci_dev;
- unsigned char *iomem;
+ unsigned char __iomem *iomem;
/*struct i2c_adapter i2c_adapter;*/
diff --git a/drivers/media/pci/pt3/Kconfig b/drivers/media/pci/pt3/Kconfig
new file mode 100644
index 0000000..16c208a
--- /dev/null
+++ b/drivers/media/pci/pt3/Kconfig
@@ -0,0 +1,10 @@
+config DVB_PT3
+ tristate "Earthsoft PT3 cards"
+ depends on DVB_CORE && PCI && I2C
+ select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QM1D1C0042 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL301RF if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for Earthsoft PT3 PCIe cards.
+
+ Say Y or M if you own such a device and want to use it.
diff --git a/drivers/media/pci/pt3/Makefile b/drivers/media/pci/pt3/Makefile
new file mode 100644
index 0000000..396f146
--- /dev/null
+++ b/drivers/media/pci/pt3/Makefile
@@ -0,0 +1,8 @@
+
+earth-pt3-objs += pt3.o pt3_i2c.o pt3_dma.o
+
+obj-$(CONFIG_DVB_PT3) += earth-pt3.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c
new file mode 100644
index 0000000..1fdeac1
--- /dev/null
+++ b/drivers/media/pci/pt3/pt3.c
@@ -0,0 +1,876 @@
+/*
+ * Earthsoft PT3 driver
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@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.
+ */
+
+#include <linux/freezer.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include "pt3.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static bool one_adapter;
+module_param(one_adapter, bool, 0444);
+MODULE_PARM_DESC(one_adapter, "Place FE's together under one adapter.");
+
+static int num_bufs = 4;
+module_param(num_bufs, int, 0444);
+MODULE_PARM_DESC(num_bufs, "Number of DMA buffer (188KiB) per FE.");
+
+
+static const struct i2c_algorithm pt3_i2c_algo = {
+ .master_xfer = &pt3_i2c_master_xfer,
+ .functionality = &pt3_i2c_functionality,
+};
+
+static const struct pt3_adap_config adap_conf[PT3_NUM_FE] = {
+ {
+ .demod_info = {
+ I2C_BOARD_INFO(TC90522_I2C_DEV_SAT, 0x11),
+ },
+ .tuner_info = {
+ I2C_BOARD_INFO("qm1d1c0042", 0x63),
+ },
+ .tuner_cfg.qm1d1c0042 = {
+ .lpf = 1,
+ },
+ .init_freq = 1049480 - 300,
+ },
+ {
+ .demod_info = {
+ I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x10),
+ },
+ .tuner_info = {
+ I2C_BOARD_INFO("mxl301rf", 0x62),
+ },
+ .init_freq = 515142857,
+ },
+ {
+ .demod_info = {
+ I2C_BOARD_INFO(TC90522_I2C_DEV_SAT, 0x13),
+ },
+ .tuner_info = {
+ I2C_BOARD_INFO("qm1d1c0042", 0x60),
+ },
+ .tuner_cfg.qm1d1c0042 = {
+ .lpf = 1,
+ },
+ .init_freq = 1049480 + 300,
+ },
+ {
+ .demod_info = {
+ I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x12),
+ },
+ .tuner_info = {
+ I2C_BOARD_INFO("mxl301rf", 0x61),
+ },
+ .init_freq = 521142857,
+ },
+};
+
+
+struct reg_val {
+ u8 reg;
+ u8 val;
+};
+
+static int
+pt3_demod_write(struct pt3_adapter *adap, const struct reg_val *data, int num)
+{
+ struct i2c_msg msg;
+ int i, ret;
+
+ ret = 0;
+ msg.addr = adap->i2c_demod->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ for (i = 0; i < num; i++) {
+ msg.buf = (u8 *)&data[i];
+ ret = i2c_transfer(adap->i2c_demod->adapter, &msg, 1);
+ if (ret == 0)
+ ret = -EREMOTE;
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static inline void pt3_lnb_ctrl(struct pt3_board *pt3, bool on)
+{
+ iowrite32((on ? 0x0f : 0x0c), pt3->regs[0] + REG_SYSTEM_W);
+}
+
+static inline struct pt3_adapter *pt3_find_adapter(struct dvb_frontend *fe)
+{
+ struct pt3_board *pt3;
+ int i;
+
+ if (one_adapter) {
+ pt3 = fe->dvb->priv;
+ for (i = 0; i < PT3_NUM_FE; i++)
+ if (pt3->adaps[i]->fe == fe)
+ return pt3->adaps[i];
+ }
+ return container_of(fe->dvb, struct pt3_adapter, dvb_adap);
+}
+
+/*
+ * all 4 tuners in PT3 are packaged in a can module (Sharp VA4M6JC2103).
+ * it seems that they share the power lines and Amp power line and
+ * adaps[3] controls those powers.
+ */
+static int
+pt3_set_tuner_power(struct pt3_board *pt3, bool tuner_on, bool amp_on)
+{
+ struct reg_val rv = { 0x1e, 0x99 };
+
+ if (tuner_on)
+ rv.val |= 0x40;
+ if (amp_on)
+ rv.val |= 0x04;
+ return pt3_demod_write(pt3->adaps[PT3_NUM_FE - 1], &rv, 1);
+}
+
+static int pt3_set_lna(struct dvb_frontend *fe)
+{
+ struct pt3_adapter *adap;
+ struct pt3_board *pt3;
+ u32 val;
+ int ret;
+
+ /* LNA is shared btw. 2 TERR-tuners */
+
+ adap = pt3_find_adapter(fe);
+ val = fe->dtv_property_cache.lna;
+ if (val == LNA_AUTO || val == adap->cur_lna)
+ return 0;
+
+ pt3 = adap->dvb_adap.priv;
+ if (mutex_lock_interruptible(&pt3->lock))
+ return -ERESTARTSYS;
+ if (val)
+ pt3->lna_on_cnt++;
+ else
+ pt3->lna_on_cnt--;
+
+ if (val && pt3->lna_on_cnt <= 1) {
+ pt3->lna_on_cnt = 1;
+ ret = pt3_set_tuner_power(pt3, true, true);
+ } else if (!val && pt3->lna_on_cnt <= 0) {
+ pt3->lna_on_cnt = 0;
+ ret = pt3_set_tuner_power(pt3, true, false);
+ } else
+ ret = 0;
+ mutex_unlock(&pt3->lock);
+ adap->cur_lna = (val != 0);
+ return ret;
+}
+
+static int pt3_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
+{
+ struct pt3_adapter *adap;
+ struct pt3_board *pt3;
+ bool on;
+
+ /* LNB power is shared btw. 2 SAT-tuners */
+
+ adap = pt3_find_adapter(fe);
+ on = (volt != SEC_VOLTAGE_OFF);
+ if (on == adap->cur_lnb)
+ return 0;
+ adap->cur_lnb = on;
+ pt3 = adap->dvb_adap.priv;
+ if (mutex_lock_interruptible(&pt3->lock))
+ return -ERESTARTSYS;
+ if (on)
+ pt3->lnb_on_cnt++;
+ else
+ pt3->lnb_on_cnt--;
+
+ if (on && pt3->lnb_on_cnt <= 1) {
+ pt3->lnb_on_cnt = 1;
+ pt3_lnb_ctrl(pt3, true);
+ } else if (!on && pt3->lnb_on_cnt <= 0) {
+ pt3->lnb_on_cnt = 0;
+ pt3_lnb_ctrl(pt3, false);
+ }
+ mutex_unlock(&pt3->lock);
+ return 0;
+}
+
+/* register values used in pt3_fe_init() */
+
+static const struct reg_val init0_sat[] = {
+ { 0x03, 0x01 },
+ { 0x1e, 0x10 },
+};
+static const struct reg_val init0_ter[] = {
+ { 0x01, 0x40 },
+ { 0x1c, 0x10 },
+};
+static const struct reg_val cfg_sat[] = {
+ { 0x1c, 0x15 },
+ { 0x1f, 0x04 },
+};
+static const struct reg_val cfg_ter[] = {
+ { 0x1d, 0x01 },
+};
+
+/*
+ * pt3_fe_init: initialize demod sub modules and ISDB-T tuners all at once.
+ *
+ * As for demod IC (TC90522) and ISDB-T tuners (MxL301RF),
+ * the i2c sequences for init'ing them are not public and hidden in a ROM,
+ * and include the board specific configurations as well.
+ * They are stored in a lump and cannot be taken out / accessed separately,
+ * thus cannot be moved to the FE/tuner driver.
+ */
+static int pt3_fe_init(struct pt3_board *pt3)
+{
+ int i, ret;
+ struct dvb_frontend *fe;
+
+ pt3_i2c_reset(pt3);
+ ret = pt3_init_all_demods(pt3);
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev, "Failed to init demod chips.");
+ return ret;
+ }
+
+ /* additional config? */
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ fe = pt3->adaps[i]->fe;
+
+ if (fe->ops.delsys[0] == SYS_ISDBS)
+ ret = pt3_demod_write(pt3->adaps[i],
+ init0_sat, ARRAY_SIZE(init0_sat));
+ else
+ ret = pt3_demod_write(pt3->adaps[i],
+ init0_ter, ARRAY_SIZE(init0_ter));
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev,
+ "demod[%d] faild in init sequence0.", i);
+ return ret;
+ }
+ ret = fe->ops.init(fe);
+ if (ret < 0)
+ return ret;
+ }
+
+ usleep_range(2000, 4000);
+ ret = pt3_set_tuner_power(pt3, true, false);
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev, "Failed to control tuner module.");
+ return ret;
+ }
+
+ /* output pin configuration */
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ fe = pt3->adaps[i]->fe;
+ if (fe->ops.delsys[0] == SYS_ISDBS)
+ ret = pt3_demod_write(pt3->adaps[i],
+ cfg_sat, ARRAY_SIZE(cfg_sat));
+ else
+ ret = pt3_demod_write(pt3->adaps[i],
+ cfg_ter, ARRAY_SIZE(cfg_ter));
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev,
+ "demod[%d] faild in init sequence1.", i);
+ return ret;
+ }
+ }
+ usleep_range(4000, 6000);
+
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ fe = pt3->adaps[i]->fe;
+ if (fe->ops.delsys[0] != SYS_ISDBS)
+ continue;
+ /* init and wake-up ISDB-S tuners */
+ ret = fe->ops.tuner_ops.init(fe);
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev,
+ "Failed to init SAT-tuner[%d].", i);
+ return ret;
+ }
+ }
+ ret = pt3_init_all_mxl301rf(pt3);
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev, "Failed to init TERR-tuners.");
+ return ret;
+ }
+
+ ret = pt3_set_tuner_power(pt3, true, true);
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev, "Failed to control tuner module.");
+ return ret;
+ }
+
+ /* Wake up all tuners and make an initial tuning,
+ * in order to avoid interference among the tuners in the module,
+ * according to the doc from the manufacturer.
+ */
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ fe = pt3->adaps[i]->fe;
+ ret = 0;
+ if (fe->ops.delsys[0] == SYS_ISDBT)
+ ret = fe->ops.tuner_ops.init(fe);
+ /* set only when called from pt3_probe(), not resume() */
+ if (ret == 0 && fe->dtv_property_cache.frequency == 0) {
+ fe->dtv_property_cache.frequency =
+ adap_conf[i].init_freq;
+ ret = fe->ops.tuner_ops.set_params(fe);
+ }
+ if (ret < 0) {
+ dev_warn(&pt3->pdev->dev,
+ "Failed in initial tuning of tuner[%d].", i);
+ return ret;
+ }
+ }
+
+ /* and sleep again, waiting to be opened by users. */
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ fe = pt3->adaps[i]->fe;
+ if (fe->ops.tuner_ops.sleep)
+ ret = fe->ops.tuner_ops.sleep(fe);
+ if (ret < 0)
+ break;
+ if (fe->ops.sleep)
+ ret = fe->ops.sleep(fe);
+ if (ret < 0)
+ break;
+ if (fe->ops.delsys[0] == SYS_ISDBS)
+ fe->ops.set_voltage = &pt3_set_voltage;
+ else
+ fe->ops.set_lna = &pt3_set_lna;
+ }
+ if (i < PT3_NUM_FE) {
+ dev_warn(&pt3->pdev->dev, "FE[%d] failed to standby.", i);
+ return ret;
+ }
+ return 0;
+}
+
+
+static int pt3_attach_fe(struct pt3_board *pt3, int i)
+{
+ struct i2c_board_info info;
+ struct tc90522_config cfg;
+ struct i2c_client *cl;
+ struct dvb_adapter *dvb_adap;
+ int ret;
+
+ info = adap_conf[i].demod_info;
+ cfg = adap_conf[i].demod_cfg;
+ cfg.tuner_i2c = NULL;
+ info.platform_data = &cfg;
+
+ ret = -ENODEV;
+ request_module("tc90522");
+ cl = i2c_new_device(&pt3->i2c_adap, &info);
+ if (!cl || !cl->dev.driver)
+ return -ENODEV;
+ pt3->adaps[i]->i2c_demod = cl;
+ if (!try_module_get(cl->dev.driver->owner))
+ goto err_demod_i2c_unregister_device;
+
+ if (!strncmp(cl->name, TC90522_I2C_DEV_SAT, sizeof(cl->name))) {
+ struct qm1d1c0042_config tcfg;
+
+ tcfg = adap_conf[i].tuner_cfg.qm1d1c0042;
+ tcfg.fe = cfg.fe;
+ info = adap_conf[i].tuner_info;
+ info.platform_data = &tcfg;
+ request_module("qm1d1c0042");
+ cl = i2c_new_device(cfg.tuner_i2c, &info);
+ } else {
+ struct mxl301rf_config tcfg;
+
+ tcfg = adap_conf[i].tuner_cfg.mxl301rf;
+ tcfg.fe = cfg.fe;
+ info = adap_conf[i].tuner_info;
+ info.platform_data = &tcfg;
+ request_module("mxl301rf");
+ cl = i2c_new_device(cfg.tuner_i2c, &info);
+ }
+ if (!cl || !cl->dev.driver)
+ goto err_demod_module_put;
+ pt3->adaps[i]->i2c_tuner = cl;
+ if (!try_module_get(cl->dev.driver->owner))
+ goto err_tuner_i2c_unregister_device;
+
+ dvb_adap = &pt3->adaps[one_adapter ? 0 : i]->dvb_adap;
+ ret = dvb_register_frontend(dvb_adap, cfg.fe);
+ if (ret < 0)
+ goto err_tuner_module_put;
+ pt3->adaps[i]->fe = cfg.fe;
+ return 0;
+
+err_tuner_module_put:
+ module_put(pt3->adaps[i]->i2c_tuner->dev.driver->owner);
+err_tuner_i2c_unregister_device:
+ i2c_unregister_device(pt3->adaps[i]->i2c_tuner);
+err_demod_module_put:
+ module_put(pt3->adaps[i]->i2c_demod->dev.driver->owner);
+err_demod_i2c_unregister_device:
+ i2c_unregister_device(pt3->adaps[i]->i2c_demod);
+
+ return ret;
+}
+
+
+static int pt3_fetch_thread(void *data)
+{
+ struct pt3_adapter *adap = data;
+ ktime_t delay;
+ bool was_frozen;
+
+#define PT3_INITIAL_BUF_DROPS 4
+#define PT3_FETCH_DELAY 10
+#define PT3_FETCH_DELAY_DELTA 2
+
+ pt3_init_dmabuf(adap);
+ adap->num_discard = PT3_INITIAL_BUF_DROPS;
+
+ dev_dbg(adap->dvb_adap.device,
+ "PT3: [%s] started.\n", adap->thread->comm);
+ set_freezable();
+ while (!kthread_freezable_should_stop(&was_frozen)) {
+ if (was_frozen)
+ adap->num_discard = PT3_INITIAL_BUF_DROPS;
+
+ pt3_proc_dma(adap);
+
+ delay = ktime_set(0, PT3_FETCH_DELAY * NSEC_PER_MSEC);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ freezable_schedule_hrtimeout_range(&delay,
+ PT3_FETCH_DELAY_DELTA * NSEC_PER_MSEC,
+ HRTIMER_MODE_REL);
+ }
+ dev_dbg(adap->dvb_adap.device,
+ "PT3: [%s] exited.\n", adap->thread->comm);
+ adap->thread = NULL;
+ return 0;
+}
+
+static int pt3_start_streaming(struct pt3_adapter *adap)
+{
+ struct task_struct *thread;
+
+ /* start fetching thread */
+ thread = kthread_run(pt3_fetch_thread, adap, "pt3-ad%i-dmx%i",
+ adap->dvb_adap.num, adap->dmxdev.dvbdev->id);
+ if (IS_ERR(thread)) {
+ int ret = PTR_ERR(thread);
+
+ dev_warn(adap->dvb_adap.device,
+ "PT3 (adap:%d, dmx:%d): failed to start kthread.\n",
+ adap->dvb_adap.num, adap->dmxdev.dvbdev->id);
+ return ret;
+ }
+ adap->thread = thread;
+
+ return pt3_start_dma(adap);
+}
+
+static int pt3_stop_streaming(struct pt3_adapter *adap)
+{
+ int ret;
+
+ ret = pt3_stop_dma(adap);
+ if (ret)
+ dev_warn(adap->dvb_adap.device,
+ "PT3: failed to stop streaming of adap:%d/FE:%d\n",
+ adap->dvb_adap.num, adap->fe->id);
+
+ /* kill the fetching thread */
+ ret = kthread_stop(adap->thread);
+ return ret;
+}
+
+static int pt3_start_feed(struct dvb_demux_feed *feed)
+{
+ struct pt3_adapter *adap;
+
+ if (signal_pending(current))
+ return -EINTR;
+
+ adap = container_of(feed->demux, struct pt3_adapter, demux);
+ adap->num_feeds++;
+ if (adap->thread)
+ return 0;
+ if (adap->num_feeds != 1) {
+ dev_warn(adap->dvb_adap.device,
+ "%s: unmatched start/stop_feed in adap:%i/dmx:%i.\n",
+ __func__, adap->dvb_adap.num, adap->dmxdev.dvbdev->id);
+ adap->num_feeds = 1;
+ }
+
+ return pt3_start_streaming(adap);
+
+}
+
+static int pt3_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct pt3_adapter *adap;
+
+ adap = container_of(feed->demux, struct pt3_adapter, demux);
+
+ adap->num_feeds--;
+ if (adap->num_feeds > 0 || !adap->thread)
+ return 0;
+ adap->num_feeds = 0;
+
+ return pt3_stop_streaming(adap);
+}
+
+
+static int pt3_alloc_adapter(struct pt3_board *pt3, int index)
+{
+ int ret;
+ struct pt3_adapter *adap;
+ struct dvb_adapter *da;
+
+ adap = kzalloc(sizeof(*adap), GFP_KERNEL);
+ if (!adap) {
+ dev_err(&pt3->pdev->dev, "failed to alloc mem for adapter.\n");
+ return -ENOMEM;
+ }
+ pt3->adaps[index] = adap;
+ adap->adap_idx = index;
+
+ if (index == 0 || !one_adapter) {
+ ret = dvb_register_adapter(&adap->dvb_adap, "PT3 DVB",
+ THIS_MODULE, &pt3->pdev->dev, adapter_nr);
+ if (ret < 0) {
+ dev_err(&pt3->pdev->dev,
+ "failed to register adapter dev.\n");
+ goto err_mem;
+ }
+ da = &adap->dvb_adap;
+ } else
+ da = &pt3->adaps[0]->dvb_adap;
+
+ adap->dvb_adap.priv = pt3;
+ adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+ adap->demux.priv = adap;
+ adap->demux.feednum = 256;
+ adap->demux.filternum = 256;
+ adap->demux.start_feed = pt3_start_feed;
+ adap->demux.stop_feed = pt3_stop_feed;
+ ret = dvb_dmx_init(&adap->demux);
+ if (ret < 0) {
+ dev_err(&pt3->pdev->dev, "failed to init dmx dev.\n");
+ goto err_adap;
+ }
+
+ adap->dmxdev.filternum = 256;
+ adap->dmxdev.demux = &adap->demux.dmx;
+ ret = dvb_dmxdev_init(&adap->dmxdev, da);
+ if (ret < 0) {
+ dev_err(&pt3->pdev->dev, "failed to init dmxdev.\n");
+ goto err_demux;
+ }
+
+ ret = pt3_alloc_dmabuf(adap);
+ if (ret) {
+ dev_err(&pt3->pdev->dev, "failed to alloc DMA buffers.\n");
+ goto err_dmabuf;
+ }
+
+ return 0;
+
+err_dmabuf:
+ pt3_free_dmabuf(adap);
+ dvb_dmxdev_release(&adap->dmxdev);
+err_demux:
+ dvb_dmx_release(&adap->demux);
+err_adap:
+ if (index == 0 || !one_adapter)
+ dvb_unregister_adapter(da);
+err_mem:
+ kfree(adap);
+ pt3->adaps[index] = NULL;
+ return ret;
+}
+
+static void pt3_cleanup_adapter(struct pt3_board *pt3, int index)
+{
+ struct pt3_adapter *adap;
+ struct dmx_demux *dmx;
+
+ adap = pt3->adaps[index];
+ if (adap == NULL)
+ return;
+
+ /* stop demux kthread */
+ if (adap->thread)
+ pt3_stop_streaming(adap);
+
+ dmx = &adap->demux.dmx;
+ dmx->close(dmx);
+ if (adap->fe) {
+ adap->fe->callback = NULL;
+ if (adap->fe->frontend_priv)
+ dvb_unregister_frontend(adap->fe);
+ if (adap->i2c_tuner) {
+ module_put(adap->i2c_tuner->dev.driver->owner);
+ i2c_unregister_device(adap->i2c_tuner);
+ }
+ if (adap->i2c_demod) {
+ module_put(adap->i2c_demod->dev.driver->owner);
+ i2c_unregister_device(adap->i2c_demod);
+ }
+ }
+ pt3_free_dmabuf(adap);
+ dvb_dmxdev_release(&adap->dmxdev);
+ dvb_dmx_release(&adap->demux);
+ if (index == 0 || !one_adapter)
+ dvb_unregister_adapter(&adap->dvb_adap);
+ kfree(adap);
+ pt3->adaps[index] = NULL;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int pt3_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct pt3_board *pt3 = pci_get_drvdata(pdev);
+ int i;
+ struct pt3_adapter *adap;
+
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ adap = pt3->adaps[i];
+ if (adap->num_feeds > 0)
+ pt3_stop_dma(adap);
+ dvb_frontend_suspend(adap->fe);
+ pt3_free_dmabuf(adap);
+ }
+
+ pt3_lnb_ctrl(pt3, false);
+ pt3_set_tuner_power(pt3, false, false);
+ return 0;
+}
+
+static int pt3_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct pt3_board *pt3 = pci_get_drvdata(pdev);
+ int i, ret;
+ struct pt3_adapter *adap;
+
+ ret = pt3_fe_init(pt3);
+ if (ret)
+ return ret;
+
+ if (pt3->lna_on_cnt > 0)
+ pt3_set_tuner_power(pt3, true, true);
+ if (pt3->lnb_on_cnt > 0)
+ pt3_lnb_ctrl(pt3, true);
+
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ adap = pt3->adaps[i];
+ dvb_frontend_resume(adap->fe);
+ ret = pt3_alloc_dmabuf(adap);
+ if (ret) {
+ dev_err(&pt3->pdev->dev, "failed to alloc DMA bufs.\n");
+ continue;
+ }
+ if (adap->num_feeds > 0)
+ pt3_start_dma(adap);
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_PM_SLEEP */
+
+
+static void pt3_remove(struct pci_dev *pdev)
+{
+ struct pt3_board *pt3;
+ int i;
+
+ pt3 = pci_get_drvdata(pdev);
+ for (i = PT3_NUM_FE - 1; i >= 0; i--)
+ pt3_cleanup_adapter(pt3, i);
+ i2c_del_adapter(&pt3->i2c_adap);
+ kfree(pt3->i2c_buf);
+ pci_iounmap(pt3->pdev, pt3->regs[0]);
+ pci_iounmap(pt3->pdev, pt3->regs[1]);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ kfree(pt3);
+}
+
+static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ u8 rev;
+ u32 ver;
+ int i, ret;
+ struct pt3_board *pt3;
+ struct i2c_adapter *i2c;
+
+ if (pci_read_config_byte(pdev, PCI_REVISION_ID, &rev) || rev != 1)
+ return -ENODEV;
+
+ ret = pci_enable_device(pdev);
+ if (ret < 0)
+ return -ENODEV;
+ pci_set_master(pdev);
+
+ ret = pci_request_regions(pdev, DRV_NAME);
+ if (ret < 0)
+ goto err_disable_device;
+
+ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+ if (ret == 0)
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+ else {
+ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret == 0)
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ else {
+ dev_err(&pdev->dev, "Failed to set DMA mask.\n");
+ goto err_release_regions;
+ }
+ dev_info(&pdev->dev, "Use 32bit DMA.\n");
+ }
+
+ pt3 = kzalloc(sizeof(*pt3), GFP_KERNEL);
+ if (!pt3) {
+ dev_err(&pdev->dev, "Failed to alloc mem for this dev.\n");
+ ret = -ENOMEM;
+ goto err_release_regions;
+ }
+ pci_set_drvdata(pdev, pt3);
+ pt3->pdev = pdev;
+ mutex_init(&pt3->lock);
+ pt3->regs[0] = pci_ioremap_bar(pdev, 0);
+ pt3->regs[1] = pci_ioremap_bar(pdev, 2);
+ if (pt3->regs[0] == NULL || pt3->regs[1] == NULL) {
+ dev_err(&pdev->dev, "Failed to ioremap.\n");
+ ret = -ENOMEM;
+ goto err_kfree;
+ }
+
+ ver = ioread32(pt3->regs[0] + REG_VERSION);
+ if ((ver >> 16) != 0x0301) {
+ dev_warn(&pdev->dev, "PT%d, I/F-ver.:%d not supported",
+ ver >> 24, (ver & 0x00ff0000) >> 16);
+ ret = -ENODEV;
+ goto err_iounmap;
+ }
+
+ pt3->num_bufs = clamp_val(num_bufs, MIN_DATA_BUFS, MAX_DATA_BUFS);
+
+ pt3->i2c_buf = kmalloc(sizeof(*pt3->i2c_buf), GFP_KERNEL);
+ if (pt3->i2c_buf == NULL) {
+ dev_err(&pdev->dev, "Failed to alloc mem for i2c.\n");
+ ret = -ENOMEM;
+ goto err_iounmap;
+ }
+ i2c = &pt3->i2c_adap;
+ i2c->owner = THIS_MODULE;
+ i2c->algo = &pt3_i2c_algo;
+ i2c->algo_data = NULL;
+ i2c->dev.parent = &pdev->dev;
+ strlcpy(i2c->name, DRV_NAME, sizeof(i2c->name));
+ i2c_set_adapdata(i2c, pt3);
+ ret = i2c_add_adapter(i2c);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to add i2c adapter.\n");
+ goto err_i2cbuf;
+ }
+
+ for (i = 0; i < PT3_NUM_FE; i++) {
+ ret = pt3_alloc_adapter(pt3, i);
+ if (ret < 0)
+ break;
+
+ ret = pt3_attach_fe(pt3, i);
+ if (ret < 0)
+ break;
+ }
+ if (i < PT3_NUM_FE) {
+ dev_err(&pdev->dev, "Failed to create FE%d.\n", i);
+ goto err_cleanup_adapters;
+ }
+
+ ret = pt3_fe_init(pt3);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to init frontends.\n");
+ i = PT3_NUM_FE - 1;
+ goto err_cleanup_adapters;
+ }
+
+ dev_info(&pdev->dev,
+ "successfully init'ed PT%d (fw:0x%02x, I/F:0x%02x).\n",
+ ver >> 24, (ver >> 8) & 0xff, (ver >> 16) & 0xff);
+ return 0;
+
+err_cleanup_adapters:
+ while (i >= 0)
+ pt3_cleanup_adapter(pt3, i--);
+ i2c_del_adapter(i2c);
+err_i2cbuf:
+ kfree(pt3->i2c_buf);
+err_iounmap:
+ if (pt3->regs[0])
+ pci_iounmap(pdev, pt3->regs[0]);
+ if (pt3->regs[1])
+ pci_iounmap(pdev, pt3->regs[1]);
+err_kfree:
+ kfree(pt3);
+err_release_regions:
+ pci_release_regions(pdev);
+err_disable_device:
+ pci_disable_device(pdev);
+ return ret;
+
+}
+
+static const struct pci_device_id pt3_id_table[] = {
+ { PCI_DEVICE_SUB(0x1172, 0x4c15, 0xee8d, 0x0368) },
+ { },
+};
+MODULE_DEVICE_TABLE(pci, pt3_id_table);
+
+static SIMPLE_DEV_PM_OPS(pt3_pm_ops, pt3_suspend, pt3_resume);
+
+static struct pci_driver pt3_driver = {
+ .name = DRV_NAME,
+ .probe = pt3_probe,
+ .remove = pt3_remove,
+ .id_table = pt3_id_table,
+
+ .driver.pm = &pt3_pm_ops,
+};
+
+module_pci_driver(pt3_driver);
+
+MODULE_DESCRIPTION("Earthsoft PT3 Driver");
+MODULE_AUTHOR("Akihiro TSUKADA");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/pt3/pt3.h b/drivers/media/pci/pt3/pt3.h
new file mode 100644
index 0000000..1b3f2ad
--- /dev/null
+++ b/drivers/media/pci/pt3/pt3.h
@@ -0,0 +1,186 @@
+/*
+ * Earthsoft PT3 driver
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@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.
+ */
+
+#ifndef PT3_H
+#define PT3_H
+
+#include <linux/atomic.h>
+#include <linux/types.h>
+
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dmxdev.h"
+
+#include "tc90522.h"
+#include "mxl301rf.h"
+#include "qm1d1c0042.h"
+
+#define DRV_NAME KBUILD_MODNAME
+
+#define PT3_NUM_FE 4
+
+/*
+ * register index of the FPGA chip
+ */
+#define REG_VERSION 0x00
+#define REG_BUS 0x04
+#define REG_SYSTEM_W 0x08
+#define REG_SYSTEM_R 0x0c
+#define REG_I2C_W 0x10
+#define REG_I2C_R 0x14
+#define REG_RAM_W 0x18
+#define REG_RAM_R 0x1c
+#define REG_DMA_BASE 0x40 /* regs for FE[i] = REG_DMA_BASE + 0x18 * i */
+#define OFST_DMA_DESC_L 0x00
+#define OFST_DMA_DESC_H 0x04
+#define OFST_DMA_CTL 0x08
+#define OFST_TS_CTL 0x0c
+#define OFST_STATUS 0x10
+#define OFST_TS_ERR 0x14
+
+/*
+ * internal buffer for I2C
+ */
+#define PT3_I2C_MAX 4091
+struct pt3_i2cbuf {
+ u8 data[PT3_I2C_MAX];
+ u8 tmp;
+ u32 num_cmds;
+};
+
+/*
+ * DMA things
+ */
+#define TS_PACKET_SZ 188
+/* DMA transfers must not cross 4GiB, so use one page / transfer */
+#define DATA_XFER_SZ 4096
+#define DATA_BUF_XFERS 47
+/* (num_bufs * DATA_BUF_SZ) % TS_PACKET_SZ must be 0 */
+#define DATA_BUF_SZ (DATA_BUF_XFERS * DATA_XFER_SZ)
+#define MAX_DATA_BUFS 16
+#define MIN_DATA_BUFS 2
+
+#define DESCS_IN_PAGE (PAGE_SIZE / sizeof(struct xfer_desc))
+#define MAX_NUM_XFERS (MAX_DATA_BUFS * DATA_BUF_XFERS)
+#define MAX_DESC_BUFS DIV_ROUND_UP(MAX_NUM_XFERS, DESCS_IN_PAGE)
+
+/* DMA transfer description.
+ * device is passed a pointer to this struct, dma-reads it,
+ * and gets the DMA buffer ring for storing TS data.
+ */
+struct xfer_desc {
+ u32 addr_l; /* bus address of target data buffer */
+ u32 addr_h;
+ u32 size;
+ u32 next_l; /* bus adddress of the next xfer_desc */
+ u32 next_h;
+};
+
+/* A DMA mapping of a page containing xfer_desc's */
+struct xfer_desc_buffer {
+ dma_addr_t b_addr;
+ struct xfer_desc *descs; /* PAGE_SIZE (xfer_desc[DESCS_IN_PAGE]) */
+};
+
+/* A DMA mapping of a data buffer */
+struct dma_data_buffer {
+ dma_addr_t b_addr;
+ u8 *data; /* size: u8[PAGE_SIZE] */
+};
+
+/*
+ * device things
+ */
+struct pt3_adap_config {
+ struct i2c_board_info demod_info;
+ struct tc90522_config demod_cfg;
+
+ struct i2c_board_info tuner_info;
+ union tuner_config {
+ struct qm1d1c0042_config qm1d1c0042;
+ struct mxl301rf_config mxl301rf;
+ } tuner_cfg;
+ u32 init_freq;
+};
+
+struct pt3_adapter {
+ struct dvb_adapter dvb_adap; /* dvb_adap.priv => struct pt3_board */
+ int adap_idx;
+
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dvb_frontend *fe;
+ struct i2c_client *i2c_demod;
+ struct i2c_client *i2c_tuner;
+
+ /* data fetch thread */
+ struct task_struct *thread;
+ int num_feeds;
+
+ bool cur_lna;
+ bool cur_lnb; /* current LNB power status (on/off) */
+
+ /* items below are for DMA */
+ struct dma_data_buffer buffer[MAX_DATA_BUFS];
+ int buf_idx;
+ int buf_ofs;
+ int num_bufs; /* == pt3_board->num_bufs */
+ int num_discard; /* how many access units to discard initially */
+
+ struct xfer_desc_buffer desc_buf[MAX_DESC_BUFS];
+ int num_desc_bufs; /* == num_bufs * DATA_BUF_XFERS / DESCS_IN_PAGE */
+};
+
+
+struct pt3_board {
+ struct pci_dev *pdev;
+ void __iomem *regs[2];
+ /* regs[0]: registers, regs[1]: internal memory, used for I2C */
+
+ struct mutex lock;
+
+ /* LNB power shared among sat-FEs */
+ int lnb_on_cnt; /* LNB power on count */
+
+ /* LNA shared among terr-FEs */
+ int lna_on_cnt; /* booster enabled count */
+
+ int num_bufs; /* number of DMA buffers allocated/mapped per FE */
+
+ struct i2c_adapter i2c_adap;
+ struct pt3_i2cbuf *i2c_buf;
+
+ struct pt3_adapter *adaps[PT3_NUM_FE];
+};
+
+
+/*
+ * prototypes
+ */
+extern int pt3_alloc_dmabuf(struct pt3_adapter *adap);
+extern void pt3_init_dmabuf(struct pt3_adapter *adap);
+extern void pt3_free_dmabuf(struct pt3_adapter *adap);
+extern int pt3_start_dma(struct pt3_adapter *adap);
+extern int pt3_stop_dma(struct pt3_adapter *adap);
+extern int pt3_proc_dma(struct pt3_adapter *adap);
+
+extern int pt3_i2c_master_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num);
+extern u32 pt3_i2c_functionality(struct i2c_adapter *adap);
+extern void pt3_i2c_reset(struct pt3_board *pt3);
+extern int pt3_init_all_demods(struct pt3_board *pt3);
+extern int pt3_init_all_mxl301rf(struct pt3_board *pt3);
+#endif /* PT3_H */
diff --git a/drivers/media/pci/pt3/pt3_dma.c b/drivers/media/pci/pt3/pt3_dma.c
new file mode 100644
index 0000000..f0ce904
--- /dev/null
+++ b/drivers/media/pci/pt3/pt3_dma.c
@@ -0,0 +1,225 @@
+/*
+ * Earthsoft PT3 driver
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@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.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include "pt3.h"
+
+#define PT3_ACCESS_UNIT (TS_PACKET_SZ * 128)
+#define PT3_BUF_CANARY (0x74)
+
+static u32 get_dma_base(int idx)
+{
+ int i;
+
+ i = (idx == 1 || idx == 2) ? 3 - idx : idx;
+ return REG_DMA_BASE + 0x18 * i;
+}
+
+int pt3_stop_dma(struct pt3_adapter *adap)
+{
+ struct pt3_board *pt3 = adap->dvb_adap.priv;
+ u32 base;
+ u32 stat;
+ int retry;
+
+ base = get_dma_base(adap->adap_idx);
+ stat = ioread32(pt3->regs[0] + base + OFST_STATUS);
+ if (!(stat & 0x01))
+ return 0;
+
+ iowrite32(0x02, pt3->regs[0] + base + OFST_DMA_CTL);
+ for (retry = 0; retry < 5; retry++) {
+ stat = ioread32(pt3->regs[0] + base + OFST_STATUS);
+ if (!(stat & 0x01))
+ return 0;
+ msleep(50);
+ }
+ return -EIO;
+}
+
+int pt3_start_dma(struct pt3_adapter *adap)
+{
+ struct pt3_board *pt3 = adap->dvb_adap.priv;
+ u32 base = get_dma_base(adap->adap_idx);
+
+ iowrite32(0x02, pt3->regs[0] + base + OFST_DMA_CTL);
+ iowrite32(lower_32_bits(adap->desc_buf[0].b_addr),
+ pt3->regs[0] + base + OFST_DMA_DESC_L);
+ iowrite32(upper_32_bits(adap->desc_buf[0].b_addr),
+ pt3->regs[0] + base + OFST_DMA_DESC_H);
+ iowrite32(0x01, pt3->regs[0] + base + OFST_DMA_CTL);
+ return 0;
+}
+
+
+static u8 *next_unit(struct pt3_adapter *adap, int *idx, int *ofs)
+{
+ *ofs += PT3_ACCESS_UNIT;
+ if (*ofs >= DATA_BUF_SZ) {
+ *ofs -= DATA_BUF_SZ;
+ (*idx)++;
+ if (*idx == adap->num_bufs)
+ *idx = 0;
+ }
+ return &adap->buffer[*idx].data[*ofs];
+}
+
+int pt3_proc_dma(struct pt3_adapter *adap)
+{
+ int idx, ofs;
+
+ idx = adap->buf_idx;
+ ofs = adap->buf_ofs;
+
+ if (adap->buffer[idx].data[ofs] == PT3_BUF_CANARY)
+ return 0;
+
+ while (*next_unit(adap, &idx, &ofs) != PT3_BUF_CANARY) {
+ u8 *p;
+
+ p = &adap->buffer[adap->buf_idx].data[adap->buf_ofs];
+ if (adap->num_discard > 0)
+ adap->num_discard--;
+ else if (adap->buf_ofs + PT3_ACCESS_UNIT > DATA_BUF_SZ) {
+ dvb_dmx_swfilter_packets(&adap->demux, p,
+ (DATA_BUF_SZ - adap->buf_ofs) / TS_PACKET_SZ);
+ dvb_dmx_swfilter_packets(&adap->demux,
+ adap->buffer[idx].data, ofs / TS_PACKET_SZ);
+ } else
+ dvb_dmx_swfilter_packets(&adap->demux, p,
+ PT3_ACCESS_UNIT / TS_PACKET_SZ);
+
+ *p = PT3_BUF_CANARY;
+ adap->buf_idx = idx;
+ adap->buf_ofs = ofs;
+ }
+ return 0;
+}
+
+void pt3_init_dmabuf(struct pt3_adapter *adap)
+{
+ int idx, ofs;
+ u8 *p;
+
+ idx = 0;
+ ofs = 0;
+ p = adap->buffer[0].data;
+ /* mark the whole buffers as "not written yet" */
+ while (idx < adap->num_bufs) {
+ p[ofs] = PT3_BUF_CANARY;
+ ofs += PT3_ACCESS_UNIT;
+ if (ofs >= DATA_BUF_SZ) {
+ ofs -= DATA_BUF_SZ;
+ idx++;
+ p = adap->buffer[idx].data;
+ }
+ }
+ adap->buf_idx = 0;
+ adap->buf_ofs = 0;
+}
+
+void pt3_free_dmabuf(struct pt3_adapter *adap)
+{
+ struct pt3_board *pt3;
+ int i;
+
+ pt3 = adap->dvb_adap.priv;
+ for (i = 0; i < adap->num_bufs; i++)
+ dma_free_coherent(&pt3->pdev->dev, DATA_BUF_SZ,
+ adap->buffer[i].data, adap->buffer[i].b_addr);
+ adap->num_bufs = 0;
+
+ for (i = 0; i < adap->num_desc_bufs; i++)
+ dma_free_coherent(&pt3->pdev->dev, PAGE_SIZE,
+ adap->desc_buf[i].descs, adap->desc_buf[i].b_addr);
+ adap->num_desc_bufs = 0;
+}
+
+
+int pt3_alloc_dmabuf(struct pt3_adapter *adap)
+{
+ struct pt3_board *pt3;
+ void *p;
+ int i, j;
+ int idx, ofs;
+ int num_desc_bufs;
+ dma_addr_t data_addr, desc_addr;
+ struct xfer_desc *d;
+
+ pt3 = adap->dvb_adap.priv;
+ adap->num_bufs = 0;
+ adap->num_desc_bufs = 0;
+ for (i = 0; i < pt3->num_bufs; i++) {
+ p = dma_alloc_coherent(&pt3->pdev->dev, DATA_BUF_SZ,
+ &adap->buffer[i].b_addr, GFP_KERNEL);
+ if (p == NULL)
+ goto failed;
+ adap->buffer[i].data = p;
+ adap->num_bufs++;
+ }
+ pt3_init_dmabuf(adap);
+
+ /* build circular-linked pointers (xfer_desc) to the data buffers*/
+ idx = 0;
+ ofs = 0;
+ num_desc_bufs =
+ DIV_ROUND_UP(adap->num_bufs * DATA_BUF_XFERS, DESCS_IN_PAGE);
+ for (i = 0; i < num_desc_bufs; i++) {
+ p = dma_alloc_coherent(&pt3->pdev->dev, PAGE_SIZE,
+ &desc_addr, GFP_KERNEL);
+ if (p == NULL)
+ goto failed;
+ adap->num_desc_bufs++;
+ adap->desc_buf[i].descs = p;
+ adap->desc_buf[i].b_addr = desc_addr;
+
+ if (i > 0) {
+ d = &adap->desc_buf[i - 1].descs[DESCS_IN_PAGE - 1];
+ d->next_l = lower_32_bits(desc_addr);
+ d->next_h = upper_32_bits(desc_addr);
+ }
+ for (j = 0; j < DESCS_IN_PAGE; j++) {
+ data_addr = adap->buffer[idx].b_addr + ofs;
+ d = &adap->desc_buf[i].descs[j];
+ d->addr_l = lower_32_bits(data_addr);
+ d->addr_h = upper_32_bits(data_addr);
+ d->size = DATA_XFER_SZ;
+
+ desc_addr += sizeof(struct xfer_desc);
+ d->next_l = lower_32_bits(desc_addr);
+ d->next_h = upper_32_bits(desc_addr);
+
+ ofs += DATA_XFER_SZ;
+ if (ofs >= DATA_BUF_SZ) {
+ ofs -= DATA_BUF_SZ;
+ idx++;
+ if (idx >= adap->num_bufs) {
+ desc_addr = adap->desc_buf[0].b_addr;
+ d->next_l = lower_32_bits(desc_addr);
+ d->next_h = upper_32_bits(desc_addr);
+ return 0;
+ }
+ }
+ }
+ }
+ return 0;
+
+failed:
+ pt3_free_dmabuf(adap);
+ return -ENOMEM;