/*
 * Copyright (C) 1999 Ulf Carlsson <ulfc@bun.falkenberg.se>
 * Copyright (C) 2001 Ladislav Michl <ladis@psi.cz>
 * Copyright (C) 2001 Petter Reinholdtsen <pere@hungry.com>
 */

#include <asm/addrspace.h>
#include <asm/system.h>

/* VINO video size */

#define VINO_PAL_WIDTH		768
#define VINO_PAL_HEIGHT		576
#define VINO_NTSC_WIDTH		646
#define VINO_NTSC_HEIGHT	486

/* set this to some sensible values. note: VINO_MIN_WIDTH have to be 8*x */
#define VINO_MIN_WIDTH		32
#define VINO_MIN_HEIGHT		32

/* channel selection */

#define VINO_INPUT_COMPOSITE    0
#define VINO_INPUT_SVIDEO	1
#define VINO_INPUT_CAMERA       2

/* color mode selection for analog input */

#define VINO_COLORS_AUTO	0
#define VINO_COLORS_MONO	1
#define VINO_COLORS_COLOR	2

/* analog signal detection bits */

#define VINO_COMPOSITE_ACTIVE	0x01
#define VINO_COMPOSITE_NTSC	0x02
#define VINO_SVIDEO_ACTIVE	0x04
#define VINO_SVIDEO_NTSC	0x08

/* i2c register readable/writeable */

#define I2C_REG_READ		0x01
#define I2C_REG_WRITE		0x02

/* VINO AISIC register definitions */

#define VINO_BASE		0x00080000	/* Vino is in the EISA address
						 * space, but it is not an
						 * EISA bus card */

#define VINO_REVID		0x0000
#define VINO_CTRL		0x0008
#define VINO_INTSTAT		0x0010	/* Interrupt status */
#define VINO_I2C_CTRL		0x0018
#define VINO_I2C_DATA		0x0020

/*
 * Calculate register address by adding the base, the channel base and
 * the channel address together. To get the address of channel B
 * alpha-register: VINO_BASE + VINO_B_BASE + VINO_ALPHA = 0x000800B0
 */

#define VINO_A_BASE             0x0028
#define VINO_B_BASE             0x00b0

#define VINO_ALPHA              0x0000  /* Alpha value */
#define VINO_CLIPS              0x0008  /* Clipping start */
#define VINO_CLIPE              0x0010  /* Clipping end */
#define VINO_FRAMERT            0x0018  /* Framerate */
#define VINO_FLDCNT             0x0020  /* Field counter */
#define VINO_LNSZ               0x0028  /* Line size */
#define VINO_LNCNT              0x0030  /* Line count */
#define VINO_PGIX               0x0038  /* Page index */
#define VINO_DESC_PTR           0x0040  /* Ptr to next four descriptors */
#define VINO_DESC_TLB_PTR       0x0048  /* Ptr to start of descriptor table */
#define VINO_DESC_DATA0         0x0050  /* Descriptor data 0 */
#define VINO_DESC_DATA1         0x0058  /* ... */
#define VINO_DESC_DATA2         0x0060
#define VINO_DESC_DATA3         0x0068
#define VINO_FIFO_THRESHOLD     0x0070  /* FIFO threshold */
#define VINO_FIFO_RP            0x0078  /* FIFO read pointer (GIO) */
#define VINO_FIFO_WP            0x0080  /* FIFO write pointer (video) */

/* Bits in the VINO_REVID register */

#define VINO_CHIP_ID		0xb
#define VINO_REV_NUM(x)		((x) & 0x0f)
#define VINO_ID_VALUE(x)	(((x) & 0xf0) >> 4)
	
/* Bits in the VINO_CTRL register */

#define VINO_CTRL_LITTLE_ENDIAN		(1<<0)
#define VINO_CTRL_A_FIELD_TRANS_INT	(1<<1)	/* Field transferred int */
#define VINO_CTRL_A_FIFO_OF_INT		(1<<2)	/* FIFO overflow int */
#define VINO_CTRL_A_END_DESC_TBL_INT	(1<<3)	/* End of desc table int */
#define VINO_CTRL_B_FIELD_TRANS_INT	(1<<4)	/* Field transferred int */
#define VINO_CTRL_B_FIFO_OF_INT		(1<<5)	/* FIFO overflow int */
#define VINO_CTRL_B_END_DESC_TBL_INT	(1<<6)	/* End of desc table int */
#define VINO_CTRL_A_DMA_ENBL		(1<<7)
#define VINO_CTRL_A_INTERLEAVE_ENBL	(1<<8)
#define VINO_CTRL_A_SYNC_ENBL		(1<<9)
#define VINO_CTRL_A_SELECT		(1<<10)	/* 1=D1 0=Philips */
#define VINO_CTRL_A_RGB			(1<<11)	/* 1=RGB 0=YUV */
#define VINO_CTRL_A_LUMA_ONLY		(1<<12)
#define VINO_CTRL_A_DEC_ENBL		(1<<13)	/* Decimation */
#define VINO_CTRL_A_DEC_SCALE_MASK	0x1c000	/* bits 14:17 */
#define VINO_CTRL_A_DEC_HOR_ONLY	(1<<17)	/* Horizontal only */
#define VINO_CTRL_A_DITHER		(1<<18)	/* 24 -> 8 bit dither */
#define VINO_CTRL_B_DMA_ENBL		(1<<19)
#define VINO_CTRL_B_INTERLEAVE_ENBL	(1<<20)
#define VINO_CTRL_B_SYNC_ENBL		(1<<21)
#define VINO_CTRL_B_SELECT		(1<<22)	/* 1=D1 0=Philips */
#define VINO_CTRL_B_RGB			(1<<23)	/* 1=RGB 0=YUV */
#define VINO_CTRL_B_LUMA_ONLY		(1<<24)
#define VINO_CTRL_B_DEC_ENBL		(1<<25)	/* Decimation */
#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 25:28 */
#define VINO_CTRL_B_DEC_HOR_ONLY	(1<<29)	/* Decimation horizontal only */
#define VINO_CTRL_B_DITHER		(1<<30)	/* ChanB 24 -> 8 bit dither */

/* Bits in the Descriptor data register */

#define VINO_DESC_JUMP			(1<<30)
#define VINO_DESC_STOP			(1<<31)
#define VINO_DESC_VALID			(1<<32)

/* Bits in the Interrupt and Status register */

#define VINO_INTSTAT_A_FIELD_TRANS	(1<<0)	/* Field transferred int */
#define VINO_INTSTAT_A_FIFO_OF		(1<<1)	/* FIFO overflow int */
#define VINO_INTSTAT_A_END_DESC_TBL	(1<<2)	/* End of desc table int */
#define VINO_INTSTAT_B_FIELD_TRANS	(1<<3)	/* Field transferred int */
#define VINO_INTSTAT_B_FIFO_OF		(1<<4)	/* FIFO overflow int */
#define VINO_INTSTAT_B_END_DESC_TBL	(1<<5)	/* End of desc table int */

/* Bits in the Clipping register */

#define VINO_CLIP_START(x)		((x) & 0x3ff)		/* bits 0:9 */
#define VINO_CLIP_ODD(x)		(((x) & 0x1ff) << 10)	/* bits 10:18 */
#define VINO_CLIP_EVEN(x)		(((x) & 0x1ff) << 19)	/* bits 19:27 */

/* Bits in the Frame Rate register */

#define VINO_FRAMERT_PAL		(1<<0)			/* 0=NTSC 1=PAL */
#define VINO_FRAMERT_RT(x)		(((x) & 0x1fff) << 1)	/* bits 1:12 */

/* Bits in the VINO_I2C_CTRL */

#define VINO_CTRL_I2C_IDLE		(1<<0)	/* write: 0=force idle
						 * read: 0=idle 1=not idle */
#define VINO_CTRL_I2C_DIR		(1<<1)	/* 0=write 1=read */
#define VINO_CTRL_I2C_MORE_BYTES	(1<<2)	/* 0=last byte 1=more bytes */
#define VINO_CTRL_I2C_TRANS_BUSY	(1<<4)	/* 0=trans done 1=trans busy */
#define VINO_CTRL_I2C_ACK		(1<<5)	/* 0=ack received 1=ack not */
#define VINO_CTRL_I2C_BUS_ERROR		(1<<7)	/* 0=no bus err 1=bus err */

/* Phillips 7191 DMSD i2c bus address */

#define DMSD_ADDR			0x8A

/* Phillips 7191 DMSD register subaddresses. */

#define DMSD_REG_IDEL			0x00
#define DMSD_REG_HSYB			0x01
#define DMSD_REG_HSYS			0x02
#define DMSD_REG_HCLB			0x03
#define DMSD_REG_HCLS			0x04
#define DMSD_REG_HPHI			0x05
#define DMSD_REG_LUMA			0x06
#define DMSD_REG_HUEC			0x07
#define DMSD_REG_CKTQ			0x08
#define DMSD_REG_CKTS			0x09
#define DMSD_REG_PLSE			0x0A
#define DMSD_REG_SESE			0x0B
#define DMSD_REG_GAIN			0x0C
#define DMSD_REG_STDC			0x0D
#define DMSD_REG_IOCK			0x0E
#define DMSD_REG_CTL3			0x0F
#define DMSD_REG_CTL4			0x10
#define DMSD_REG_CHCV			0x11
#define DMSD_REG_HS6B			0x14
#define DMSD_REG_HS6S			0x15
#define DMSD_REG_HC6B			0x16
#define DMSD_REG_HC6S			0x17
#define DMSD_REG_HP6I			0x18
#define DMSD_REG_STATUS			0xFF	/* not really a subaddress */

/*  Phillips 7191 DMSD - Status Register definitions */

#define DMSD_STATUS_CODE		0x01	/* color detected flag */
#define DMSD_STATUS_FIDT		0x20	/* Format type NTSC/PAL */
#define DMSD_STATUS_HLCK		0x40	/* PLL unlocked/locked */
#define DMSD_STATUS_STTC		0x80	/* tv/vtr time constant */

/* Phillips 7191 DMSD - Luminance Control Register definitions */

#define DMSD_BYPS_MASK			0x7F		/* bit 7 */
#define DMSD_BYPS_SHIFT			7
#define DMSD_BYPS_SVID			0x80
#define DMSD_PREF_MASK			0xBF		/* bit 6 */
#define DMSD_PREF_SHIFT			6
#define DMSD_BPSS_MASK			0xCF		/* bits 5 - 4 */
#define DMSD_BPSS_SHIFT			4
#define DMSD_CORI_MASK			0xF3		/* bits 3 - 2 */
#define DMSD_CORI_SHIFT			2
#define DMSD_APER_MASK			0xFC		/* bits 1 - 0 */
#define DMSD_APER_SHIFT			0

/* Phillips 7191 DMSD - Colour-killer threshold QAM reg definitions */

#define DMSD_CKTQ_MASK			0x07		/* bits 7 - 3 */
#define DMSD_CKTQ_SHIFT			3

/* Phillips 7191 DMSD - Colour-killer threshold SECAM reg definitions */

#define DMSD_CKTS_MASK			0x07		/* bits 7 - 3 */
#define DMSD_CKTS_SHIFT			3

/* Phillips 7191 DMSD - Gain control register definitions */

#define DMSD_COLO_MASK			0x7F		/* bit 7 */
#define DMSD_COLO_SHIFT			7
#define DMSD_LFIS_MASK			0x9F		/* bits 6 - 5 */
#define DMSD_LFIS_SHIFT			5

/* Phillips 7191 DMSD - Standard/Mode control register definitions */

#define DMSD_VTRC_MASK			0x7F		/* bit 7 */
#define DMSD_VTRC_SHIFT			7
#define DMSD_NFEN_MASK			0xF7		/* bit 3 */
#define DMSD_NFEN_SHIFT			3
#define DMSD_HRMV_MASK			0xFB		/* bit 2 */
#define DMSD_HRMV_SHIFT			2
#define DMSD_SECS_MASK			0xFE            /* bit 0 */
#define DMSD_SECS_SHIFT			0

/* Phillips 7191 DMSD - I/O and Clock Control Register definitions */

#define DMSD_HPLL_MASK			0x7F		/* bit 7 */
#define DMSD_HPLL_SHIFT			7
#define DMSD_CHRS_MASK			0xFB		/* bit 2 */
#define DMSD_CHRS_SHIFT			2
#define DMSD_CHRS_SVID			0x04
#define DMSD_GPSW_MASK			0xFC		/* bits 1 - 0 */
#define DMSD_GPSW_SHIFT			0
#define DMSD_GPSW_CVBS			0x00
#define DMSD_GPSW_SVID			0x02

/* Phillips 7191 DMSD - Control #3 Register definitions */

#define DMSD_AUFD_MASK			0x7F		/* bit 7 */
#define DMSD_AUFD_SHIFT			7
#define DMSD_FSEL_MASK			0xBF		/* bit 6 */
#define DMSD_FSEL_SHIFT			6
#define DMSD_SXCR_MASK			0xDF		/* bit 5 */
#define DMSD_SXCR_SHIFT			5
#define DMSD_SCEN_MASK			0xEF		/* bit 4 */
#define DMSD_SCEN_SHIFT			4
#define DMSD_YDEL_MASK			0xF8		/* bits 2 - 0 */
#define DMSD_YDEL_SHIFT			0

/* Phillips 7191 DMSD - Control #4 Register definitions */

#define DMSD_VNOI_MASK			0xFC		/* bits 1 - 0 */
#define DMSD_VNOI_SHIFT			0

/* i2c address for the Guinness Camera */

#define INDYCAM_ADDR			0x56

/* Camera version */

#define CAMERA_VERSION			0x10		/* v1.0 */
#define MOOSE_CAMERA_VERSION		0x12		/* v1.2 */

/* i2c register bus addresses for the IndyCam */

#define INDYCAM_CONTROL			0x00		/* R/W */
#define INDYCAM_SHUTTER			0x01		/* R/W */
#define INDYCAM_GAIN			0x02		/* R/W */
#define INDYCAM_BRIGHTNESS		0x03		/* R/O */
#define INDYCAM_RED_BALANCE		0x04		/* R/W */
#define INDYCAM_BLUE_BALANCE		0x05		/* R/W */
#define INDYCAM_RED_SATURATION		0x06		/* R/W */
#define INDYCAM_BLUE_SATURATION		0x07		/* R/W */
#define INDYCAM_GAMMA			0x08
#define INDYCAM_VERSION			0x0e		/* R/O */
#define INDYCAM_RESET			0x0f		/* W/O */
#define INDYCAM_LED			0x46
#define INDYCAM_ORIENTATION		0x47
#define INDYCAM_BUTTON			0x48

/* Field definitions of registers for the IndyCam */

#define INDYCAM_CONTROL_AGCENA		(1<<0)		/* R/W */
#define INDYCAM_CONTROL_AWBCTL		(1<<1)		/* R/W */
							/* 2-3 are reserved */
#define INDYCAM_CONTROL_EVNFLD		(1<<4)		/* R/O */

#define INDYCAM_SHUTTER_10000		0x02		/* 1/10000 second */
#define INDYCAM_SHUTTER_4000		0x04		/* 1/4000 second */
#define INDYCAM_SHUTTER_2000		0x08		/* 1/2000 second */
#define INDYCAM_SHUTTER_1000		0x10		/* 1/1000 second */
#define INDYCAM_SHUTTER_500		0x20		/* 1/500 second */
#define INDYCAM_SHUTTER_250		0x3f		/* 1/250 second */
#define INDYCAM_SHUTTER_125		0x7e		/* 1/125 second */
#define INDYCAM_SHUTTER_100		0x9e		/* 1/100 second */
#define INDYCAM_SHUTTER_60		0x00		/* 1/60 second */

#define INDYCAM_GAIN_MAX		0xff		/* maximum gain */
#define INDYCAM_GAIN_MIN		0x00		/* minimum gain */

#define INDYCAM_RED_BALANCE_MAX		0x00
#define INDYCAM_RED_BALANCE_MIN		0xff

#define INDYCAM_BLUE_BALANCE_MAX	0x00
#define INDYCAM_BLUE_BALANCE_MIN	0xff

#define INDYCAM_RED_SATURATION_MAX	0xff
#define INDYCAM_RED_SATURATION_MIN	0x00

#define INDYCAM_BLUE_SATURATION_MAX	0xff
#define INDYCAM_BLUE_SATURATION_MIN	0x00

#define INDYCAM_VERSION_MAJOR(x)	(((x) & 0xf0) >> 4)
#define INDYCAM_VERSION_MINOR(x)	((x) & 0x0f)

#define INDYCAM_BUTTON_RELEASED		(1<<4)
#define INDYCAM_LED_ACTIVE		(1<<5)
#define INDYCAM_BOTTOM_TO_TOP		(1<<6)


/* Basic VINO register access functions */

extern __inline__ unsigned long vino_reg_read(unsigned long addr)
{
	unsigned long flags, ret;

	save_and_cli(flags);
	ret = (*(unsigned long *)(char *)KSEG1ADDR(addr + VINO_BASE + 4));
	restore_flags(flags);
	return ret;
}

extern __inline__ void vino_reg_write(unsigned long addr, unsigned long value)
{
	unsigned long flags;

	save_and_cli(flags);
	(*(unsigned long *)(char *)KSEG1ADDR(addr + VINO_BASE + 4)) = value;
	restore_flags(flags);
}

extern __inline__ void vino_reg_and(unsigned long addr, unsigned long value)
{
	unsigned long flags;

	save_and_cli(flags);
	(*(unsigned long *)(char *)KSEG1ADDR(addr + VINO_BASE + 4)) &= value;
	restore_flags(flags);
}

extern __inline__ void vino_reg_or(unsigned long addr, unsigned long value)
{
	unsigned long flags;

	save_and_cli(flags);
	(*(unsigned long *)(char *)KSEG1ADDR(addr + VINO_BASE + 4)) |= value;
	restore_flags(flags);
}
