162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Driver for the NXP SAA7164 PCIe bridge 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci Driver architecture 1062306a36Sopenharmony_ci ******************* 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c 1362306a36Sopenharmony_ci | : Standard Linux driver framework for creating 1462306a36Sopenharmony_ci | : exposing and managing interfaces to the rest 1562306a36Sopenharmony_ci | : of the kernel or userland. Also uses _fw.c to load 1662306a36Sopenharmony_ci | : firmware direct into the PCIe bus, bypassing layers. 1762306a36Sopenharmony_ci V 1862306a36Sopenharmony_ci saa7164_api..() : Translate kernel specific functions/features 1962306a36Sopenharmony_ci | : into command buffers. 2062306a36Sopenharmony_ci V 2162306a36Sopenharmony_ci saa7164_cmd..() : Manages the flow of command packets on/off, 2262306a36Sopenharmony_ci | : the bus. Deal with bus errors, timeouts etc. 2362306a36Sopenharmony_ci V 2462306a36Sopenharmony_ci saa7164_bus..() : Manage a read/write memory ring buffer in the 2562306a36Sopenharmony_ci | : PCIe Address space. 2662306a36Sopenharmony_ci | 2762306a36Sopenharmony_ci | saa7164_fw...() : Load any firmware 2862306a36Sopenharmony_ci | | : direct into the device 2962306a36Sopenharmony_ci V V 3062306a36Sopenharmony_ci <- ----------------- PCIe address space -------------------- -> 3162306a36Sopenharmony_ci*/ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#include <linux/pci.h> 3462306a36Sopenharmony_ci#include <linux/i2c.h> 3562306a36Sopenharmony_ci#include <linux/kdev_t.h> 3662306a36Sopenharmony_ci#include <linux/mutex.h> 3762306a36Sopenharmony_ci#include <linux/crc32.h> 3862306a36Sopenharmony_ci#include <linux/kthread.h> 3962306a36Sopenharmony_ci#include <linux/freezer.h> 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#include <media/tuner.h> 4262306a36Sopenharmony_ci#include <media/tveeprom.h> 4362306a36Sopenharmony_ci#include <media/dvb_demux.h> 4462306a36Sopenharmony_ci#include <media/dvb_frontend.h> 4562306a36Sopenharmony_ci#include <media/dvb_net.h> 4662306a36Sopenharmony_ci#include <media/dvbdev.h> 4762306a36Sopenharmony_ci#include <media/dmxdev.h> 4862306a36Sopenharmony_ci#include <media/v4l2-common.h> 4962306a36Sopenharmony_ci#include <media/v4l2-ioctl.h> 5062306a36Sopenharmony_ci#include <media/v4l2-device.h> 5162306a36Sopenharmony_ci#include <media/v4l2-ctrls.h> 5262306a36Sopenharmony_ci#include <media/v4l2-event.h> 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#include "saa7164-reg.h" 5562306a36Sopenharmony_ci#include "saa7164-types.h" 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define SAA7164_MAXBOARDS 8 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define UNSET (-1U) 6062306a36Sopenharmony_ci#define SAA7164_BOARD_NOAUTO UNSET 6162306a36Sopenharmony_ci#define SAA7164_BOARD_UNKNOWN 0 6262306a36Sopenharmony_ci#define SAA7164_BOARD_UNKNOWN_REV2 1 6362306a36Sopenharmony_ci#define SAA7164_BOARD_UNKNOWN_REV3 2 6462306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3 6562306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4 6662306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5 6762306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6 6862306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7 6962306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8 7062306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9 7162306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2200_5 10 7262306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2255proto 11 7362306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2255 12 7462306a36Sopenharmony_ci#define SAA7164_BOARD_HAUPPAUGE_HVR2205 13 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define SAA7164_MAX_UNITS 8 7762306a36Sopenharmony_ci#define SAA7164_TS_NUMBER_OF_LINES 312 7862306a36Sopenharmony_ci#define SAA7164_PS_NUMBER_OF_LINES 256 7962306a36Sopenharmony_ci#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */ 8062306a36Sopenharmony_ci#define SAA7164_MAX_ENCODER_BUFFERS 64 /* max 5secs of latency at 6Mbps */ 8162306a36Sopenharmony_ci#define SAA7164_MAX_VBI_BUFFERS 64 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/* Port related defines */ 8462306a36Sopenharmony_ci#define SAA7164_PORT_TS1 (0) 8562306a36Sopenharmony_ci#define SAA7164_PORT_TS2 (SAA7164_PORT_TS1 + 1) 8662306a36Sopenharmony_ci#define SAA7164_PORT_ENC1 (SAA7164_PORT_TS2 + 1) 8762306a36Sopenharmony_ci#define SAA7164_PORT_ENC2 (SAA7164_PORT_ENC1 + 1) 8862306a36Sopenharmony_ci#define SAA7164_PORT_VBI1 (SAA7164_PORT_ENC2 + 1) 8962306a36Sopenharmony_ci#define SAA7164_PORT_VBI2 (SAA7164_PORT_VBI1 + 1) 9062306a36Sopenharmony_ci#define SAA7164_MAX_PORTS (SAA7164_PORT_VBI2 + 1) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define DBGLVL_FW 4 9362306a36Sopenharmony_ci#define DBGLVL_DVB 8 9462306a36Sopenharmony_ci#define DBGLVL_I2C 16 9562306a36Sopenharmony_ci#define DBGLVL_API 32 9662306a36Sopenharmony_ci#define DBGLVL_CMD 64 9762306a36Sopenharmony_ci#define DBGLVL_BUS 128 9862306a36Sopenharmony_ci#define DBGLVL_IRQ 256 9962306a36Sopenharmony_ci#define DBGLVL_BUF 512 10062306a36Sopenharmony_ci#define DBGLVL_ENC 1024 10162306a36Sopenharmony_ci#define DBGLVL_VBI 2048 10262306a36Sopenharmony_ci#define DBGLVL_THR 4096 10362306a36Sopenharmony_ci#define DBGLVL_CPU 8192 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci#define SAA7164_NORMS \ 10662306a36Sopenharmony_ci (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP) 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/* TV frequency range copied from tuner-core.c */ 10962306a36Sopenharmony_ci#define SAA7164_TV_MIN_FREQ (44U * 16U) 11062306a36Sopenharmony_ci#define SAA7164_TV_MAX_FREQ (958U * 16U) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cienum port_t { 11362306a36Sopenharmony_ci SAA7164_MPEG_UNDEFINED = 0, 11462306a36Sopenharmony_ci SAA7164_MPEG_DVB, 11562306a36Sopenharmony_ci SAA7164_MPEG_ENCODER, 11662306a36Sopenharmony_ci SAA7164_MPEG_VBI, 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cienum saa7164_i2c_bus_nr { 12062306a36Sopenharmony_ci SAA7164_I2C_BUS_0 = 0, 12162306a36Sopenharmony_ci SAA7164_I2C_BUS_1, 12262306a36Sopenharmony_ci SAA7164_I2C_BUS_2, 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cienum saa7164_buffer_flags { 12662306a36Sopenharmony_ci SAA7164_BUFFER_UNDEFINED = 0, 12762306a36Sopenharmony_ci SAA7164_BUFFER_FREE, 12862306a36Sopenharmony_ci SAA7164_BUFFER_BUSY, 12962306a36Sopenharmony_ci SAA7164_BUFFER_FULL 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cienum saa7164_unit_type { 13362306a36Sopenharmony_ci SAA7164_UNIT_UNDEFINED = 0, 13462306a36Sopenharmony_ci SAA7164_UNIT_DIGITAL_DEMODULATOR, 13562306a36Sopenharmony_ci SAA7164_UNIT_ANALOG_DEMODULATOR, 13662306a36Sopenharmony_ci SAA7164_UNIT_TUNER, 13762306a36Sopenharmony_ci SAA7164_UNIT_EEPROM, 13862306a36Sopenharmony_ci SAA7164_UNIT_ZILOG_IRBLASTER, 13962306a36Sopenharmony_ci SAA7164_UNIT_ENCODER, 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* The PCIe bridge doesn't grant direct access to i2c. 14362306a36Sopenharmony_ci * Instead, you address i2c devices using a uniqely 14462306a36Sopenharmony_ci * allocated 'unitid' value via a messaging API. This 14562306a36Sopenharmony_ci * is a problem. The kernel and existing demod/tuner 14662306a36Sopenharmony_ci * drivers expect to talk 'i2c', so we have to maintain 14762306a36Sopenharmony_ci * a translation layer, and a series of functions to 14862306a36Sopenharmony_ci * convert i2c bus + device address into a unit id. 14962306a36Sopenharmony_ci */ 15062306a36Sopenharmony_cistruct saa7164_unit { 15162306a36Sopenharmony_ci enum saa7164_unit_type type; 15262306a36Sopenharmony_ci u8 id; 15362306a36Sopenharmony_ci char *name; 15462306a36Sopenharmony_ci enum saa7164_i2c_bus_nr i2c_bus_nr; 15562306a36Sopenharmony_ci u8 i2c_bus_addr; 15662306a36Sopenharmony_ci u8 i2c_reg_len; 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistruct saa7164_board { 16062306a36Sopenharmony_ci char *name; 16162306a36Sopenharmony_ci enum port_t porta, portb, portc, 16262306a36Sopenharmony_ci portd, porte, portf; 16362306a36Sopenharmony_ci enum { 16462306a36Sopenharmony_ci SAA7164_CHIP_UNDEFINED = 0, 16562306a36Sopenharmony_ci SAA7164_CHIP_REV2, 16662306a36Sopenharmony_ci SAA7164_CHIP_REV3, 16762306a36Sopenharmony_ci } chiprev; 16862306a36Sopenharmony_ci struct saa7164_unit unit[SAA7164_MAX_UNITS]; 16962306a36Sopenharmony_ci}; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistruct saa7164_subid { 17262306a36Sopenharmony_ci u16 subvendor; 17362306a36Sopenharmony_ci u16 subdevice; 17462306a36Sopenharmony_ci u32 card; 17562306a36Sopenharmony_ci}; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistruct saa7164_encoder_fh { 17862306a36Sopenharmony_ci struct v4l2_fh fh; 17962306a36Sopenharmony_ci struct saa7164_port *port; 18062306a36Sopenharmony_ci atomic_t v4l_reading; 18162306a36Sopenharmony_ci}; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistruct saa7164_vbi_fh { 18462306a36Sopenharmony_ci struct v4l2_fh fh; 18562306a36Sopenharmony_ci struct saa7164_port *port; 18662306a36Sopenharmony_ci atomic_t v4l_reading; 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistruct saa7164_histogram_bucket { 19062306a36Sopenharmony_ci u32 val; 19162306a36Sopenharmony_ci u32 count; 19262306a36Sopenharmony_ci u64 update_time; 19362306a36Sopenharmony_ci}; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistruct saa7164_histogram { 19662306a36Sopenharmony_ci char name[32]; 19762306a36Sopenharmony_ci struct saa7164_histogram_bucket counter1[64]; 19862306a36Sopenharmony_ci}; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistruct saa7164_user_buffer { 20162306a36Sopenharmony_ci struct list_head list; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci /* Attributes */ 20462306a36Sopenharmony_ci u8 *data; 20562306a36Sopenharmony_ci u32 pos; 20662306a36Sopenharmony_ci u32 actual_size; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci u32 crc; 20962306a36Sopenharmony_ci}; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistruct saa7164_fw_status { 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci /* RISC Core details */ 21462306a36Sopenharmony_ci u32 status; 21562306a36Sopenharmony_ci u32 mode; 21662306a36Sopenharmony_ci u32 spec; 21762306a36Sopenharmony_ci u32 inst; 21862306a36Sopenharmony_ci u32 cpuload; 21962306a36Sopenharmony_ci u32 remainheap; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* Firmware version */ 22262306a36Sopenharmony_ci u32 version; 22362306a36Sopenharmony_ci u32 major; 22462306a36Sopenharmony_ci u32 sub; 22562306a36Sopenharmony_ci u32 rel; 22662306a36Sopenharmony_ci u32 buildnr; 22762306a36Sopenharmony_ci}; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistruct saa7164_dvb { 23062306a36Sopenharmony_ci struct mutex lock; 23162306a36Sopenharmony_ci struct dvb_adapter adapter; 23262306a36Sopenharmony_ci struct dvb_frontend *frontend; 23362306a36Sopenharmony_ci struct dvb_demux demux; 23462306a36Sopenharmony_ci struct dmxdev dmxdev; 23562306a36Sopenharmony_ci struct dmx_frontend fe_hw; 23662306a36Sopenharmony_ci struct dmx_frontend fe_mem; 23762306a36Sopenharmony_ci struct dvb_net net; 23862306a36Sopenharmony_ci int feeding; 23962306a36Sopenharmony_ci}; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cistruct saa7164_i2c { 24262306a36Sopenharmony_ci struct saa7164_dev *dev; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci enum saa7164_i2c_bus_nr nr; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* I2C I/O */ 24762306a36Sopenharmony_ci struct i2c_adapter i2c_adap; 24862306a36Sopenharmony_ci struct i2c_client i2c_client; 24962306a36Sopenharmony_ci u32 i2c_rc; 25062306a36Sopenharmony_ci}; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistruct saa7164_tvnorm { 25362306a36Sopenharmony_ci char *name; 25462306a36Sopenharmony_ci v4l2_std_id id; 25562306a36Sopenharmony_ci}; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistruct saa7164_encoder_params { 25862306a36Sopenharmony_ci struct saa7164_tvnorm encodernorm; 25962306a36Sopenharmony_ci u32 height; 26062306a36Sopenharmony_ci u32 width; 26162306a36Sopenharmony_ci u32 is_50hz; 26262306a36Sopenharmony_ci u32 bitrate; /* bps */ 26362306a36Sopenharmony_ci u32 bitrate_peak; /* bps */ 26462306a36Sopenharmony_ci u32 bitrate_mode; 26562306a36Sopenharmony_ci u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */ 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci u32 audio_sampling_freq; 26862306a36Sopenharmony_ci u32 ctl_mute; 26962306a36Sopenharmony_ci u32 ctl_aspect; 27062306a36Sopenharmony_ci u32 refdist; 27162306a36Sopenharmony_ci u32 gop_size; 27262306a36Sopenharmony_ci}; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cistruct saa7164_vbi_params { 27562306a36Sopenharmony_ci struct saa7164_tvnorm encodernorm; 27662306a36Sopenharmony_ci u32 height; 27762306a36Sopenharmony_ci u32 width; 27862306a36Sopenharmony_ci u32 is_50hz; 27962306a36Sopenharmony_ci u32 bitrate; /* bps */ 28062306a36Sopenharmony_ci u32 bitrate_peak; /* bps */ 28162306a36Sopenharmony_ci u32 bitrate_mode; 28262306a36Sopenharmony_ci u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */ 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci u32 audio_sampling_freq; 28562306a36Sopenharmony_ci u32 ctl_mute; 28662306a36Sopenharmony_ci u32 ctl_aspect; 28762306a36Sopenharmony_ci u32 refdist; 28862306a36Sopenharmony_ci u32 gop_size; 28962306a36Sopenharmony_ci}; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_cistruct saa7164_port; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistruct saa7164_buffer { 29462306a36Sopenharmony_ci struct list_head list; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci /* Note of which h/w buffer list index position we occupy */ 29762306a36Sopenharmony_ci int idx; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci struct saa7164_port *port; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci /* Hardware Specific */ 30262306a36Sopenharmony_ci /* PCI Memory allocations */ 30362306a36Sopenharmony_ci enum saa7164_buffer_flags flags; /* Free, Busy, Full */ 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci /* A block of page align PCI memory */ 30662306a36Sopenharmony_ci u32 pci_size; /* PCI allocation size in bytes */ 30762306a36Sopenharmony_ci u64 *cpu; /* Virtual address */ 30862306a36Sopenharmony_ci dma_addr_t dma; /* Physical address */ 30962306a36Sopenharmony_ci u32 crc; /* Checksum for the entire buffer data */ 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci /* A page table that splits the block into a number of entries */ 31262306a36Sopenharmony_ci u32 pt_size; /* PCI allocation size in bytes */ 31362306a36Sopenharmony_ci u64 *pt_cpu; /* Virtual address */ 31462306a36Sopenharmony_ci dma_addr_t pt_dma; /* Physical address */ 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci /* Encoder fops */ 31762306a36Sopenharmony_ci u32 pos; 31862306a36Sopenharmony_ci u32 actual_size; 31962306a36Sopenharmony_ci}; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_cistruct saa7164_port { 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci struct saa7164_dev *dev; 32462306a36Sopenharmony_ci enum port_t type; 32562306a36Sopenharmony_ci int nr; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* --- Generic port attributes --- */ 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci /* HW stream parameters */ 33062306a36Sopenharmony_ci struct tmHWStreamParameters hw_streamingparams; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci /* DMA configuration values, is seeded during initialization */ 33362306a36Sopenharmony_ci struct tmComResDMATermDescrHeader hwcfg; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci /* hardware specific registers */ 33662306a36Sopenharmony_ci u32 bufcounter; 33762306a36Sopenharmony_ci u32 pitch; 33862306a36Sopenharmony_ci u32 bufsize; 33962306a36Sopenharmony_ci u32 bufoffset; 34062306a36Sopenharmony_ci u32 bufptr32l; 34162306a36Sopenharmony_ci u32 bufptr32h; 34262306a36Sopenharmony_ci u64 bufptr64; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci u32 numpte; /* Number of entries in array, only valid in head */ 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci struct mutex dmaqueue_lock; 34762306a36Sopenharmony_ci struct saa7164_buffer dmaqueue; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci u64 last_irq_msecs, last_svc_msecs; 35062306a36Sopenharmony_ci u64 last_irq_msecs_diff, last_svc_msecs_diff; 35162306a36Sopenharmony_ci u32 last_svc_wp; 35262306a36Sopenharmony_ci u32 last_svc_rp; 35362306a36Sopenharmony_ci u64 last_irq_svc_msecs_diff; 35462306a36Sopenharmony_ci u64 last_read_msecs, last_read_msecs_diff; 35562306a36Sopenharmony_ci u64 last_poll_msecs, last_poll_msecs_diff; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci struct saa7164_histogram irq_interval; 35862306a36Sopenharmony_ci struct saa7164_histogram svc_interval; 35962306a36Sopenharmony_ci struct saa7164_histogram irq_svc_interval; 36062306a36Sopenharmony_ci struct saa7164_histogram read_interval; 36162306a36Sopenharmony_ci struct saa7164_histogram poll_interval; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci /* --- DVB Transport Specific --- */ 36462306a36Sopenharmony_ci struct saa7164_dvb dvb; 36562306a36Sopenharmony_ci struct i2c_client *i2c_client_demod; 36662306a36Sopenharmony_ci struct i2c_client *i2c_client_tuner; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci /* --- Encoder/V4L related attributes --- */ 36962306a36Sopenharmony_ci /* Encoder */ 37062306a36Sopenharmony_ci /* Defaults established in saa7164-encoder.c */ 37162306a36Sopenharmony_ci struct saa7164_tvnorm encodernorm; 37262306a36Sopenharmony_ci struct v4l2_ctrl_handler ctrl_handler; 37362306a36Sopenharmony_ci v4l2_std_id std; 37462306a36Sopenharmony_ci u32 height; 37562306a36Sopenharmony_ci u32 width; 37662306a36Sopenharmony_ci u32 freq; 37762306a36Sopenharmony_ci u8 mux_input; 37862306a36Sopenharmony_ci u8 encoder_profile; 37962306a36Sopenharmony_ci u8 video_format; 38062306a36Sopenharmony_ci u8 audio_format; 38162306a36Sopenharmony_ci u8 video_resolution; 38262306a36Sopenharmony_ci u16 ctl_brightness; 38362306a36Sopenharmony_ci u16 ctl_contrast; 38462306a36Sopenharmony_ci u16 ctl_hue; 38562306a36Sopenharmony_ci u16 ctl_saturation; 38662306a36Sopenharmony_ci u16 ctl_sharpness; 38762306a36Sopenharmony_ci s8 ctl_volume; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci struct tmComResAFeatureDescrHeader audfeat; 39062306a36Sopenharmony_ci struct tmComResEncoderDescrHeader encunit; 39162306a36Sopenharmony_ci struct tmComResProcDescrHeader vidproc; 39262306a36Sopenharmony_ci struct tmComResExtDevDescrHeader ifunit; 39362306a36Sopenharmony_ci struct tmComResTunerDescrHeader tunerunit; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci struct work_struct workenc; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci /* V4L Encoder Video */ 39862306a36Sopenharmony_ci struct saa7164_encoder_params encoder_params; 39962306a36Sopenharmony_ci struct video_device *v4l_device; 40062306a36Sopenharmony_ci atomic_t v4l_reader_count; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci struct saa7164_buffer list_buf_used; 40362306a36Sopenharmony_ci struct saa7164_buffer list_buf_free; 40462306a36Sopenharmony_ci wait_queue_head_t wait_read; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci /* V4L VBI */ 40762306a36Sopenharmony_ci struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc; 40862306a36Sopenharmony_ci struct saa7164_vbi_params vbi_params; 40962306a36Sopenharmony_ci struct saa7164_port *enc_port; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci /* Debug */ 41262306a36Sopenharmony_ci u32 sync_errors; 41362306a36Sopenharmony_ci u32 v_cc_errors; 41462306a36Sopenharmony_ci u32 a_cc_errors; 41562306a36Sopenharmony_ci u8 last_v_cc; 41662306a36Sopenharmony_ci u8 last_a_cc; 41762306a36Sopenharmony_ci u32 done_first_interrupt; 41862306a36Sopenharmony_ci}; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_cistruct saa7164_dev { 42162306a36Sopenharmony_ci struct list_head devlist; 42262306a36Sopenharmony_ci atomic_t refcount; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci struct v4l2_device v4l2_dev; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci /* pci stuff */ 42762306a36Sopenharmony_ci struct pci_dev *pci; 42862306a36Sopenharmony_ci unsigned char pci_rev, pci_lat; 42962306a36Sopenharmony_ci int pci_bus, pci_slot; 43062306a36Sopenharmony_ci u32 __iomem *lmmio; 43162306a36Sopenharmony_ci u8 __iomem *bmmio; 43262306a36Sopenharmony_ci u32 __iomem *lmmio2; 43362306a36Sopenharmony_ci u8 __iomem *bmmio2; 43462306a36Sopenharmony_ci int pci_irqmask; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci /* board details */ 43762306a36Sopenharmony_ci int nr; 43862306a36Sopenharmony_ci int hwrevision; 43962306a36Sopenharmony_ci u32 board; 44062306a36Sopenharmony_ci char name[16]; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci /* firmware status */ 44362306a36Sopenharmony_ci struct saa7164_fw_status fw_status; 44462306a36Sopenharmony_ci u32 firmwareloaded; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci struct tmComResHWDescr hwdesc; 44762306a36Sopenharmony_ci struct tmComResInterfaceDescr intfdesc; 44862306a36Sopenharmony_ci struct tmComResBusDescr busdesc; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci struct tmComResBusInfo bus; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci /* Interrupt status and ack registers */ 45362306a36Sopenharmony_ci u32 int_status; 45462306a36Sopenharmony_ci u32 int_ack; 45562306a36Sopenharmony_ci bool msi; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci struct cmd cmds[SAA_CMD_MAX_MSG_UNITS]; 45862306a36Sopenharmony_ci struct mutex lock; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci /* I2c related */ 46162306a36Sopenharmony_ci struct saa7164_i2c i2c_bus[3]; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci /* Transport related */ 46462306a36Sopenharmony_ci struct saa7164_port ports[SAA7164_MAX_PORTS]; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci /* Deferred command/api interrupts handling */ 46762306a36Sopenharmony_ci struct work_struct workcmd; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci /* A kernel thread to monitor the firmware log, used 47062306a36Sopenharmony_ci * only in debug mode. 47162306a36Sopenharmony_ci */ 47262306a36Sopenharmony_ci struct task_struct *kthread; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci}; 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ciextern struct list_head saa7164_devlist; 47762306a36Sopenharmony_ciextern unsigned int waitsecs; 47862306a36Sopenharmony_ciextern unsigned int encoder_buffers; 47962306a36Sopenharmony_ciextern unsigned int vbi_buffers; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 48262306a36Sopenharmony_ci/* saa7164-core.c */ 48362306a36Sopenharmony_civoid saa7164_dumpregs(struct saa7164_dev *dev, u32 addr); 48462306a36Sopenharmony_civoid saa7164_getfirmwarestatus(struct saa7164_dev *dev); 48562306a36Sopenharmony_ciu32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev); 48662306a36Sopenharmony_civoid saa7164_histogram_update(struct saa7164_histogram *hg, u32 val); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 48962306a36Sopenharmony_ci/* saa7164-fw.c */ 49062306a36Sopenharmony_ciint saa7164_downloadfirmware(struct saa7164_dev *dev); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 49362306a36Sopenharmony_ci/* saa7164-i2c.c */ 49462306a36Sopenharmony_ciextern int saa7164_i2c_register(struct saa7164_i2c *bus); 49562306a36Sopenharmony_ciextern int saa7164_i2c_unregister(struct saa7164_i2c *bus); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 49862306a36Sopenharmony_ci/* saa7164-bus.c */ 49962306a36Sopenharmony_ciint saa7164_bus_setup(struct saa7164_dev *dev); 50062306a36Sopenharmony_civoid saa7164_bus_dump(struct saa7164_dev *dev); 50162306a36Sopenharmony_ciint saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, 50262306a36Sopenharmony_ci void *buf); 50362306a36Sopenharmony_ciint saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, 50462306a36Sopenharmony_ci void *buf, int peekonly); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 50762306a36Sopenharmony_ci/* saa7164-cmd.c */ 50862306a36Sopenharmony_ciint saa7164_cmd_send(struct saa7164_dev *dev, 50962306a36Sopenharmony_ci u8 id, enum tmComResCmd command, u16 controlselector, 51062306a36Sopenharmony_ci u16 size, void *buf); 51162306a36Sopenharmony_civoid saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno); 51262306a36Sopenharmony_ciint saa7164_irq_dequeue(struct saa7164_dev *dev); 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 51562306a36Sopenharmony_ci/* saa7164-api.c */ 51662306a36Sopenharmony_ciint saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version); 51762306a36Sopenharmony_ciint saa7164_api_enum_subdevs(struct saa7164_dev *dev); 51862306a36Sopenharmony_ciint saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, 51962306a36Sopenharmony_ci u32 datalen, u8 *data); 52062306a36Sopenharmony_ciint saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, 52162306a36Sopenharmony_ci u32 datalen, u8 *data); 52262306a36Sopenharmony_ciint saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr, 52362306a36Sopenharmony_ci u32 datalen, u8 *data); 52462306a36Sopenharmony_ciint saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen); 52562306a36Sopenharmony_ciint saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); 52662306a36Sopenharmony_ciint saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); 52762306a36Sopenharmony_ciint saa7164_api_transition_port(struct saa7164_port *port, u8 mode); 52862306a36Sopenharmony_ciint saa7164_api_initialize_dif(struct saa7164_port *port); 52962306a36Sopenharmony_ciint saa7164_api_configure_dif(struct saa7164_port *port, u32 std); 53062306a36Sopenharmony_ciint saa7164_api_set_encoder(struct saa7164_port *port); 53162306a36Sopenharmony_ciint saa7164_api_get_encoder(struct saa7164_port *port); 53262306a36Sopenharmony_ciint saa7164_api_set_aspect_ratio(struct saa7164_port *port); 53362306a36Sopenharmony_ciint saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl); 53462306a36Sopenharmony_ciint saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl); 53562306a36Sopenharmony_ciint saa7164_api_set_videomux(struct saa7164_port *port); 53662306a36Sopenharmony_ciint saa7164_api_audio_mute(struct saa7164_port *port, int mute); 53762306a36Sopenharmony_ciint saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level); 53862306a36Sopenharmony_ciint saa7164_api_set_audio_std(struct saa7164_port *port); 53962306a36Sopenharmony_ciint saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect); 54062306a36Sopenharmony_ciint saa7164_api_get_videomux(struct saa7164_port *port); 54162306a36Sopenharmony_ciint saa7164_api_set_vbi_format(struct saa7164_port *port); 54262306a36Sopenharmony_ciint saa7164_api_set_debug(struct saa7164_dev *dev, u8 level); 54362306a36Sopenharmony_ciint saa7164_api_collect_debug(struct saa7164_dev *dev); 54462306a36Sopenharmony_ciint saa7164_api_get_load_info(struct saa7164_dev *dev, 54562306a36Sopenharmony_ci struct tmFwInfoStruct *i); 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 54862306a36Sopenharmony_ci/* saa7164-cards.c */ 54962306a36Sopenharmony_ciextern struct saa7164_board saa7164_boards[]; 55062306a36Sopenharmony_ciextern const unsigned int saa7164_bcount; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ciextern struct saa7164_subid saa7164_subids[]; 55362306a36Sopenharmony_ciextern const unsigned int saa7164_idcount; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ciextern void saa7164_card_list(struct saa7164_dev *dev); 55662306a36Sopenharmony_ciextern void saa7164_gpio_setup(struct saa7164_dev *dev); 55762306a36Sopenharmony_ciextern void saa7164_card_setup(struct saa7164_dev *dev); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ciextern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr); 56062306a36Sopenharmony_ciextern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr); 56162306a36Sopenharmony_ciextern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 56462306a36Sopenharmony_ci/* saa7164-dvb.c */ 56562306a36Sopenharmony_ciextern int saa7164_dvb_register(struct saa7164_port *port); 56662306a36Sopenharmony_ciextern int saa7164_dvb_unregister(struct saa7164_port *port); 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 56962306a36Sopenharmony_ci/* saa7164-buffer.c */ 57062306a36Sopenharmony_ciextern struct saa7164_buffer *saa7164_buffer_alloc( 57162306a36Sopenharmony_ci struct saa7164_port *port, u32 len); 57262306a36Sopenharmony_ciextern int saa7164_buffer_dealloc(struct saa7164_buffer *buf); 57362306a36Sopenharmony_ciextern void saa7164_buffer_display(struct saa7164_buffer *buf); 57462306a36Sopenharmony_ciextern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i); 57562306a36Sopenharmony_ciextern int saa7164_buffer_cfg_port(struct saa7164_port *port); 57662306a36Sopenharmony_ciextern struct saa7164_user_buffer *saa7164_buffer_alloc_user( 57762306a36Sopenharmony_ci struct saa7164_dev *dev, u32 len); 57862306a36Sopenharmony_ciextern void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf); 57962306a36Sopenharmony_ciextern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 58262306a36Sopenharmony_ci/* saa7164-encoder.c */ 58362306a36Sopenharmony_ciint saa7164_s_std(struct saa7164_port *port, v4l2_std_id id); 58462306a36Sopenharmony_ciint saa7164_g_std(struct saa7164_port *port, v4l2_std_id *id); 58562306a36Sopenharmony_ciint saa7164_enum_input(struct file *file, void *priv, struct v4l2_input *i); 58662306a36Sopenharmony_ciint saa7164_g_input(struct saa7164_port *port, unsigned int *i); 58762306a36Sopenharmony_ciint saa7164_s_input(struct saa7164_port *port, unsigned int i); 58862306a36Sopenharmony_ciint saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t); 58962306a36Sopenharmony_ciint saa7164_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t); 59062306a36Sopenharmony_ciint saa7164_g_frequency(struct saa7164_port *port, struct v4l2_frequency *f); 59162306a36Sopenharmony_ciint saa7164_s_frequency(struct saa7164_port *port, 59262306a36Sopenharmony_ci const struct v4l2_frequency *f); 59362306a36Sopenharmony_ciint saa7164_encoder_register(struct saa7164_port *port); 59462306a36Sopenharmony_civoid saa7164_encoder_unregister(struct saa7164_port *port); 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 59762306a36Sopenharmony_ci/* saa7164-vbi.c */ 59862306a36Sopenharmony_ciint saa7164_vbi_register(struct saa7164_port *port); 59962306a36Sopenharmony_civoid saa7164_vbi_unregister(struct saa7164_port *port); 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci/* ----------------------------------------------------------- */ 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ciextern unsigned int crc_checking; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ciextern unsigned int saa_debug; 60662306a36Sopenharmony_ci#define dprintk(level, fmt, arg...)\ 60762306a36Sopenharmony_ci do { if (saa_debug & level)\ 60862306a36Sopenharmony_ci printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ 60962306a36Sopenharmony_ci } while (0) 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci#define log_warn(fmt, arg...)\ 61262306a36Sopenharmony_ci do { \ 61362306a36Sopenharmony_ci printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\ 61462306a36Sopenharmony_ci } while (0) 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2)) 61762306a36Sopenharmony_ci#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2)) 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci#define saa7164_readb(reg) readl(dev->bmmio + (reg)) 62062306a36Sopenharmony_ci#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg)) 62162306a36Sopenharmony_ci 622