/* * Driver for the NXP SAA7164 PCIe bridge * * Copyright (c) 2010 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* TODO: Cleanup and shorten the namespace */ /* Some structues are passed directly to/from the firmware and * have strict alignment requirements. This is one of them. */ struct tmComResHWDescr { u8 bLength; u8 bDescriptorType; u8 bDescriptorSubtype; u16 bcdSpecVersion; u32 dwClockFrequency; u32 dwClockUpdateRes; u8 bCapabilities; u32 dwDeviceRegistersLocation; u32 dwHostMemoryRegion; u32 dwHostMemoryRegionSize; u32 dwHostHibernatMemRegion; u32 dwHostHibernatMemRegionSize; } __attribute__((packed)); /* This is DWORD aligned on windows but I can't find the right * gcc syntax to match the binary data from the device. * I've manually padded with Reserved[3] bytes to match the hardware, * but this could break if GCC decies to pack in a different way. */ struct tmComResInterfaceDescr { u8 bLength; u8 bDescriptorType; u8 bDescriptorSubtype; u8 bFlags; u8 bInterfaceType; u8 bInterfaceId; u8 bBaseInterface; u8 bInterruptId; u8 bDebugInterruptId; u8 BARLocation; u8 Reserved[3]; }; struct tmComResBusDescr { u64 CommandRing; u64 ResponseRing; u32 CommandWrite; u32 CommandRead; u32 ResponseWrite; u32 ResponseRead; }; enum tmBusType { NONE = 0, TYPE_BUS_PCI = 1, TYPE_BUS_PCIe = 2, TYPE_BUS_USB = 3, TYPE_BUS_I2C = 4 }; struct tmComResBusInfo { enum tmBusType Type; u16 m_wMaxReqSize; u8 *m_pdwSetRing; u32 m_dwSizeSetRing; u8 *m_pdwGetRing; u32 m_dwSizeGetRing; u32 m_dwSetWritePos; u32 m_dwSetReadPos; u32 m_dwGetWritePos; u32 m_dwGetReadPos; /* All access is protected */ struct mutex lock; }; struct tmComResInfo { u8 id; u8 flags; u16 size; u32 command; u16 controlselector; u8 seqno; } __attribute__((packed)); enum tmComResCmd { SET_CUR = 0x01, GET_CUR = 0x81, GET_MIN = 0x82, GET_MAX = 0x83, GET_RES = 0x84, GET_LEN = 0x85, GET_INFO = 0x86, GET_DEF = 0x87 }; struct cmd { u8 seqno; u32 inuse; u32 timeout; u32 signalled; struct mutex lock; wait_queue_head_t wait; }; struct tmDescriptor { u32 pathid; u32 size; void *descriptor; }; struct tmComResDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; } __attribute__((packed)); struct tmComResExtDevDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; u32 devicetype; u16 deviceid; u32 numgpiopins; u8 numgpiogroups; u8 controlsize; } __attribute__((packed)); struct tmComResGPIO { u32 pin; u8 state; } __attribute__((packed)); struct tmComResPathDescrHeader { u8 len; u8 type; u8 subtype; u8 pathid; } __attribute__((packed)); /* terminaltype */ enum tmComResTermType { ITT_ANTENNA = 0x0203, LINE_CONNECTOR = 0x0603, SPDIF_CONNECTOR = 0x0605, COMPOSITE_CONNECTOR = 0x0401, SVIDEO_CONNECTOR = 0x0402, COMPONENT_CONNECTOR = 0x0403, STANDARD_DMA = 0xF101 }; struct tmComResAntTermDescrHeader { u8 len; u8 type; u8 subtype; u8 terminalid; u16 terminaltype; u8 assocterminal; u8 iterminal; u8 controlsize; } __attribute__((packed)); struct tmComResTunerDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; u8 sourceid; u8 iunit; u32 tuningstandards; u8 controlsize; u32 controls; } __attribute__((packed)); enum tmBufferFlag { /* the buffer does not contain any valid data */ TM_BUFFER_FLAG_EMPTY, /* the buffer is filled with valid data */ TM_BUFFER_FLAG_DONE, /* the buffer is the dummy buffer - TODO??? */ TM_BUFFER_FLAG_DUMMY_BUFFER }; struct tmBuffer { u64 *pagetablevirt; u64 pagetablephys; u16 offset; u8 *context; u64 timestamp; enum tmBufferFlag BufferFlag; u32 lostbuffers; u32 validbuffers; u64 *dummypagevirt; u64 dummypagephys; u64 *addressvirt; }; struct tmHWStreamParameters { u32 bitspersample; u32 samplesperline; u32 numberoflines; u32 pitch; u32 linethreshold; u64 **pagetablelistvirt; u64 *pagetablelistphys; u32 numpagetables; u32 numpagetableentries; }; struct tmStreamParameters { struct tmHWStreamParameters HWStreamParameters; u64 qwDummyPageTablePhys; u64 *pDummyPageTableVirt; }; struct tmComResDMATermDescrHeader { u8 len; u8 type; u8 subtyle; u8 unitid; u16 terminaltype; u8 assocterminal; u8 sourceid; u8 iterminal; u32 BARLocation; u8 flags; u8 interruptid; u8 buffercount; u8 metadatasize; u8 numformats; u8 controlsize; } __attribute__((packed)); /* * * Description: * This is the transport stream format header. * * Settings: * bLength - The size of this descriptor in bytes. * bDescriptorType - CS_INTERFACE. * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype. * bFormatIndex - A non-zero constant that uniquely identifies the * format. * bDataOffset - Offset to TSP packet within MPEG-2 TS transport * stride, in bytes. * bPacketLength - Length of TSP packet, in bytes (typically 188). * bStrideLength - Length of MPEG-2 TS transport stride. * guidStrideFormat - A Globally Unique Identifier indicating the * format of the stride data (if any). Set to zeros * if there is no Stride Data, or if the Stride * Data is to be ignored by the application. * */ struct tmComResTSFormatDescrHeader { u8 len; u8 type; u8 subtype; u8 bFormatIndex; u8 bDataOffset; u8 bPacketLength; u8 bStrideLength; u8 guidStrideFormat[16]; } __attribute__((packed)); /* Encoder related structures */ /* A/V Mux Selector */ struct tmComResSelDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; u8 nrinpins; u8 sourceid; } __attribute__((packed)); /* A/V Audio processor definitions */ struct tmComResProcDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; u8 sourceid; u16 wreserved; u8 controlsize; } __attribute__((packed)); /* Video bitrate control message */ #define EU_VIDEO_BIT_RATE_MODE_CONSTANT (0) #define EU_VIDEO_BIT_RATE_MODE_VARIABLE_AVERAGE (1) #define EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK (2) struct tmComResEncVideoBitRate { u8 ucVideoBitRateMode; u32 dwVideoBitRate; u32 dwVideoBitRatePeak; } __attribute__((packed)); /* Video Encoder Aspect Ratio message */ struct tmComResEncVideoInputAspectRatio { u8 width; u8 height; } __attribute__((packed)); /* Video Encoder GOP IBP message */ /* 1. IPPPPPPPPPPPPPP */ /* 2. IBPBPBPBPBPBPBP */ /* 3. IBBPBBPBBPBBP */ #define SAA7164_ENCODER_DEFAULT_GOP_DIST (1) #define SAA7164_ENCODER_DEFAULT_GOP_SIZE (15) struct tmComResEncVideoGopStructure { u8 ucGOPSize; /* GOP Size 12, 15 */ u8 ucRefFrameDist; /* Reference Frame Distance */ } __attribute__((packed)); /* Encoder processor definition */ struct tmComResEncoderDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; u8 vsourceid; u8 asourceid; u8 iunit; u32 dwmControlCap; u32 dwmProfileCap; u32 dwmVidFormatCap; u8 bmVidBitrateCap; u16 wmVidResolutionsCap; u16 wmVidFrmRateCap; u32 dwmAudFormatCap; u8 bmAudBitrateCap; } __attribute__((packed)); /* Audio processor definition */ struct tmComResAFeatureDescrHeader { u8 len; u8 type; u8 subtype; u8 unitid; u8 sourceid; u8 controlsize; } __attribute__((packed)); /* Audio control messages */ struct tmComResAudioDefaults { u8 ucDecoderLevel; u8 ucDecoderFM_Level; u8 ucMonoLevel; u8 ucNICAM_Level; u8 ucSAP_Level; u8 ucADC_Level; } __attribute__((packed)); /* Audio bitrate control message */ struct tmComResEncAudioBitRate { u8 ucAudioBitRateMode; u32 dwAudioBitRate; u32 dwAudioBitRatePeak; } __attribute__((packed)); /* Tuner / AV Decoder messages */ struct tmComResTunerStandard { u8 std; u32 country; } __attribute__((packed)); struct tmComResTunerStandardAuto { u8 mode; } __attribute__((packed)); /* EEPROM definition for PS stream types */ struct tmComResPSFormatDescrHeader { u8 len; u8 type; u8 subtype; u8 bFormatIndex; u16 wPacketLength; u16 wPackLength; u8 bPackDataType; } __attribute__((packed)); /* VBI control structure */ struct tmComResVBIFormatDescrHeader { u8 len; u8 type; u8 subtype; /* VS_FORMAT_VBI */ u8 bFormatIndex; u32 VideoStandard; /* See KS_AnalogVideoStandard, NTSC = 1 */ u8 StartLine; /* NTSC Start = 10 */ u8 EndLine; /* NTSC = 21 */ u8 FieldRate; /* 60 for NTSC */ u8 bNumLines; /* Unused - scheduled for removal */ } __attribute__((packed)); struct tmComResProbeCommit { u16 bmHint; u8 bFormatIndex; u8 bFrameIndex; } __attribute__((packed)); struct tmComResDebugSetLevel { u32 dwDebugLevel; } __attribute__((packed)); struct tmComResDebugGetData { u32 dwResult; u8 ucDebugData[256]; } __attribute__((packed)); struct tmFwInfoStruct { u32 status; u32 mode; u32 devicespec; u32 deviceinst; u32 CPULoad; u32 RemainHeap; u32 CPUClock; u32 RAMSpeed; } __attribute__((packed));