Commit e33951e1 authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] update the av7110 and budget drivers

 - update the av7110 and budget drivers
 - replaced ddelay() wait function with generic dvb_delay()
   implementation
 - new DATA_MPEG_VIDEO_EVENT for direct mpeg2 video playback
 - added support for DVB-C cards with MSP3400 mixer and analog tuner
 - fixed up the av7110_ir handler and especially the write_proc()
   function; this fixed the bug the Stanford Checker has found
parent 33e9942c
......@@ -75,6 +75,8 @@
#include "dvb_i2c.h"
#include "dvb_frontend.h"
#include "dvb_functions.h"
#if 1
#define DEBUG_VARIABLE av7110_debug
......@@ -87,15 +89,16 @@
#include "av7110.h"
#include "av7110_ipack.h"
static int AV_StartPlay(av7110_t *av7110, int av);
static void restart_feeds(av7110_t *av7110);
static int bootarm(av7110_t *av7110);
static inline int i2c_writereg(av7110_t *av7110, u8 id, u8 reg, u8 val);
static inline u8 i2c_readreg(av7110_t *av7110, u8 id, u8 reg);
static int outcom(av7110_t *av7110, int type, int com, int num, ...);
static void SetMode(av7110_t *av7110, int mode);
static int AV_StartPlay(struct av7110 *av7110, int av);
static void restart_feeds(struct av7110 *av7110);
static int bootarm(struct av7110 *av7110);
static inline int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
static int outcom(struct av7110 *av7110, int type, int com, int num, ...);
static void SetMode(struct av7110 *av7110, int mode);
static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event);
void pes_to_ts(u8 const *buf, long int length, u16 pid, p2t_t *p);
void pes_to_ts(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed);
static int av7110_debug = 0;
......@@ -107,20 +110,7 @@ static int hw_sections = 1;
int av7110_num = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME av7110
#endif
/****************************************************************************
* General helper functions
****************************************************************************/
static inline void ddelay(int i)
{
current->state=TASK_INTERRUPTIBLE;
schedule_timeout((HZ*i)/100);
}
#define FW_CI_LL_SUPPORT(arm_app) (((arm_app) >> 16) & 0x8000)
/****************************************************************************
* DEBI functions
......@@ -130,7 +120,7 @@ static inline void ddelay(int i)
by Nathan Laredo <laredo@gnu.org> */
static
int wait_for_debi_done(av7110_t *av7110)
int wait_for_debi_done(struct av7110 *av7110)
{
struct saa7146_dev *dev = av7110->dev;
int start;
......@@ -163,7 +153,7 @@ int wait_for_debi_done(av7110_t *av7110)
return 0;
}
static int debiwrite(av7110_t *av7110, u32 config,
static int debiwrite(struct av7110 *av7110, u32 config,
int addr, u32 val, int count)
{
struct saa7146_dev *dev = av7110->dev;
......@@ -183,7 +173,7 @@ static int debiwrite(av7110_t *av7110, u32 config,
return 0;
}
static u32 debiread(av7110_t *av7110, u32 config, int addr, int count)
static u32 debiread(struct av7110 *av7110, u32 config, int addr, int count)
{
struct saa7146_dev *dev = av7110->dev;
u32 result = 0;
......@@ -207,8 +197,10 @@ static u32 debiread(av7110_t *av7110, u32 config, int addr, int count)
/* DEBI during interrupt */
/* fixme: val can be a pointer to a memory or an u32 value -- this
won't work on 64bit platforms! */
static inline void
iwdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
{
if (count>4 && val)
memcpy(av7110->debi_virt, (char *) val, count);
......@@ -216,7 +208,7 @@ iwdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
}
static inline u32
irdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
{
u32 res;
......@@ -229,7 +221,7 @@ irdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
/* DEBI outside interrupts, only for count<=4! */
static inline void
wdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
{
unsigned long flags;
......@@ -239,7 +231,7 @@ wdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
}
static inline u32
rdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count)
rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
{
unsigned long flags;
u32 res;
......@@ -263,7 +255,7 @@ chtrans(char c)
/* handle mailbox registers of the dual ported RAM */
static inline void
ARM_ResetMailBox(av7110_t *av7110)
ARM_ResetMailBox(struct av7110 *av7110)
{
unsigned long flags;
......@@ -277,19 +269,19 @@ ARM_ResetMailBox(av7110_t *av7110)
}
static inline void
ARM_ClearMailBox(av7110_t *av7110)
ARM_ClearMailBox(struct av7110 *av7110)
{
iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
}
static inline void
ARM_ClearIrq(av7110_t *av7110)
ARM_ClearIrq(struct av7110 *av7110)
{
irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
}
static void
reset_arm(av7110_t *av7110)
reset_arm(struct av7110 *av7110)
{
saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
......@@ -316,7 +308,7 @@ reset_arm(av7110_t *av7110)
}
static void
recover_arm(av7110_t *av7110)
recover_arm(struct av7110 *av7110)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -326,12 +318,14 @@ recover_arm(av7110_t *av7110)
printk("OOPS, no current->files\n");
reset_arm(av7110);
}
ddelay(10);
dvb_delay(100);
restart_feeds(av7110);
outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
}
static void
arm_error(av7110_t *av7110)
arm_error(struct av7110 *av7110)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -342,25 +336,13 @@ arm_error(av7110_t *av7110)
static int arm_thread(void *data)
{
av7110_t *av7110 = data;
struct av7110 *av7110 = data;
u16 newloops = 0;
DEB_EE(("av7110: %p\n",av7110));
lock_kernel();
#if 0
daemonize();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
reparent_to_init ();
#endif
#else
exit_mm(current);
current->session=current->pgrp=1;
#endif
sigfillset(&current->blocked);
strcpy(current->comm, "arm_mon");
dvb_kernel_thread_setup ("arm_mon");
av7110->arm_thread = current;
unlock_kernel();
while (!av7110->arm_rmmod && !signal_pending(current)) {
interruptible_sleep_on_timeout(&av7110->arm_wait, 5*HZ);
......@@ -395,11 +377,11 @@ static int arm_thread(void *data)
static int
record_cb(dvb_filter_pes2ts_t *p2t, u8 *buf, size_t len)
record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
{
struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv;
DEB_EE(("dvb_filter_pes2ts_t:%p\n",p2t));
DEB_EE(("struct dvb_filter_pes2ts:%p\n",p2t));
if (!(dvbdmxfeed->ts_type & TS_PACKET))
return 0;
......@@ -426,7 +408,7 @@ dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
}
static int
AV_StartRecord(av7110_t *av7110, int av,
AV_StartRecord(struct av7110 *av7110, int av,
struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
......@@ -472,7 +454,7 @@ AV_StartRecord(av7110_t *av7110, int av,
}
static int
AV_StartPlay(av7110_t *av7110, int av)
AV_StartPlay(struct av7110 *av7110, int av)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -506,7 +488,7 @@ AV_StartPlay(av7110_t *av7110, int av)
}
static void
AV_Stop(av7110_t *av7110, int av)
AV_Stop(struct av7110 *av7110, int av)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -548,9 +530,9 @@ AV_Stop(av7110_t *av7110, int av)
*
* If we want to support multiple controls we would have to do much more...
*/
void av7110_setup_irc_config (av7110_t *av7110, u32 ir_config)
void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config)
{
static av7110_t *last;
static struct av7110 *last;
DEB_EE(("av7110: %p\n",av7110));
......@@ -559,8 +541,10 @@ void av7110_setup_irc_config (av7110_t *av7110, u32 ir_config)
else
last = av7110;
if (av7110)
if (av7110) {
outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
av7110->ir_config = ir_config;
}
}
static void (*irc_handler)(u32);
......@@ -585,7 +569,7 @@ void run_handlers(unsigned long ircom)
DECLARE_TASKLET(irtask,run_handlers,0);
void IR_handle(av7110_t *av7110, u32 ircom)
void IR_handle(struct av7110 *av7110, u32 ircom)
{
DEB_S(("av7110: ircommand = %08x\n", ircom));
irtask.data = (unsigned long) ircom;
......@@ -596,7 +580,7 @@ void IR_handle(av7110_t *av7110, u32 ircom)
* IRQ handling
****************************************************************************/
void CI_handle(av7110_t *av7110, u8 *data, u16 len)
void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
{
//CI_out(av7110, data, len);
......@@ -633,8 +617,8 @@ static inline int
DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len,
u8 * buffer2, size_t buffer2_len,
struct dvb_demux_filter *dvbdmxfilter,
dmx_success_t success,
av7110_t *av7110)
enum dmx_success success,
struct av7110 *av7110)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -648,7 +632,7 @@ DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len,
if ((((buffer1[1]<<8)|buffer1[2])&0xfff)+3!=buffer1_len)
return 0;
if (dvbdmxfilter->doneq) {
dmx_section_filter_t *filter=&dvbdmxfilter->filter;
struct dmx_section_filter *filter=&dvbdmxfilter->filter;
int i;
u8 xor, neq=0;
......@@ -702,7 +686,7 @@ print_time(char *s)
}
static void
ci_get_data(dvb_ringbuffer_t *cibuf, u8 *data, int len)
ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
{
if (dvb_ringbuffer_free(cibuf) < len+2)
return;
......@@ -718,7 +702,7 @@ ci_get_data(dvb_ringbuffer_t *cibuf, u8 *data, int len)
static
void debiirq (unsigned long data)
{
struct av7110_s *av7110 = (struct av7110_s*) data;
struct av7110 *av7110 = (struct av7110*) data;
int type=av7110->debitype;
int handle=(type>>8)&0x1f;
......@@ -731,8 +715,10 @@ void debiirq (unsigned long data)
if (type==-1) {
printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR));
spin_lock(&av7110->debilock);
ARM_ClearMailBox(av7110);
ARM_ClearIrq(av7110);
spin_unlock(&av7110->debilock);
return;
}
av7110->debitype=-1;
......@@ -845,7 +831,7 @@ void debiirq (unsigned long data)
}
static int
pes_play(void *dest, dvb_ringbuffer_t *buf, int dlen)
pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
{
int len;
u32 sync;
......@@ -876,14 +862,14 @@ pes_play(void *dest, dvb_ringbuffer_t *buf, int dlen)
blen|=DVB_RINGBUFFER_PEEK(buf,5);
blen+=6;
if (len<blen || blen>dlen) {
printk("buffer empty - avail %d blen %u dlen %d\n",len,blen,dlen);
//printk("buffer empty - avail %d blen %u dlen %d\n",len,blen,dlen);
wake_up(&buf->queue);
return -1;
}
(void)dvb_ringbuffer_read(buf,dest,(size_t)blen,0);
DEB_S(("pread=%08x, pwrite=%08x\n",buf->pread, buf->pwrite));
DEB_S(("pread=0x%08lx, pwrite=0x%08lx\n",(unsigned long)buf->pread, (unsigned long)buf->pwrite));
wake_up(&buf->queue);
return blen;
}
......@@ -892,7 +878,7 @@ pes_play(void *dest, dvb_ringbuffer_t *buf, int dlen)
static
void gpioirq (unsigned long data)
{
struct av7110_s *av7110 = (struct av7110_s*) data;
struct av7110 *av7110 = (struct av7110*) data;
u32 rxbuf, txbuf;
int len;
......@@ -926,10 +912,51 @@ void gpioirq (unsigned long data)
case DATA_PES_PLAY:
break;
case DATA_MPEG_VIDEO_EVENT:
{
u32 h_ar;
struct video_event event;
av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
av7110->video_size.h = h_ar & 0xfff;
DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
av7110->video_size.w,
av7110->video_size.h,
av7110->video_size.aspect_ratio));
event.type = VIDEO_EVENT_SIZE_CHANGED;
event.u.size.w = av7110->video_size.w;
event.u.size.h = av7110->video_size.h;
switch ((h_ar >> 12) & 0xf)
{
case 3:
av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
av7110->videostate.video_format = VIDEO_FORMAT_16_9;
break;
case 4:
av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
av7110->videostate.video_format = VIDEO_FORMAT_221_1;
break;
default:
av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
av7110->videostate.video_format = VIDEO_FORMAT_4_3;
}
dvb_video_add_event(av7110, &event);
break;
}
case DATA_CI_PUT:
{
int avail;
dvb_ringbuffer_t *cibuf=&av7110->ci_wbuffer;
struct dvb_ringbuffer *cibuf=&av7110->ci_wbuffer;
avail=dvb_ringbuffer_avail(cibuf);
if (avail<=2) {
......@@ -1077,7 +1104,7 @@ void gpioirq (unsigned long data)
****************************************************************************/
static int OutCommand(av7110_t *av7110, u16* buf, int length)
static int OutCommand(struct av7110 *av7110, u16* buf, int length)
{
int i;
u32 start;
......@@ -1095,7 +1122,7 @@ static int OutCommand(av7110_t *av7110, u16* buf, int length)
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) )
{
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_FREE) {
printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__);
return -1;
......@@ -1106,7 +1133,7 @@ static int OutCommand(av7110_t *av7110, u16* buf, int length)
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) )
{
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_SHAKE) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
return -1;
......@@ -1117,7 +1144,7 @@ static int OutCommand(av7110_t *av7110, u16* buf, int length)
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull )
{
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_OSD) {
printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__);
return -1;
......@@ -1137,7 +1164,7 @@ static int OutCommand(av7110_t *av7110, u16* buf, int length)
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) )
{
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_FREE) {
printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
return -1;
......@@ -1159,7 +1186,7 @@ static int OutCommand(av7110_t *av7110, u16* buf, int length)
}
inline static int
SOutCommand(av7110_t *av7110, u16* buf, int length)
SOutCommand(struct av7110 *av7110, u16* buf, int length)
{
int ret;
......@@ -1181,7 +1208,7 @@ SOutCommand(av7110_t *av7110, u16* buf, int length)
}
static int outcom(av7110_t *av7110, int type, int com, int num, ...)
static int outcom(struct av7110 *av7110, int type, int com, int num, ...)
{
va_list args;
u16 buf[num+2];
......@@ -1205,7 +1232,7 @@ static int outcom(av7110_t *av7110, int type, int com, int num, ...)
return ret;
}
int SendCICommand(av7110_t *av7110, u8 subcom, u8 *Params, u8 ParamLen)
int SendCICommand(struct av7110 *av7110, u8 subcom, u8 *Params, u8 ParamLen)
{
int i, ret;
u16 CommandBuffer[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
......@@ -1228,7 +1255,7 @@ int SendCICommand(av7110_t *av7110, u8 subcom, u8 *Params, u8 ParamLen)
}
static int CommandRequest(av7110_t *av7110, u16 *Buff, int length, u16 *buf, int n)
static int CommandRequest(struct av7110 *av7110, u16 *Buff, int length, u16 *buf, int n)
{
int err;
s16 i;
......@@ -1257,7 +1284,7 @@ static int CommandRequest(av7110_t *av7110, u16 *Buff, int length, u16 *buf, int
while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) )
{
#ifdef _NOHANDSHAKE
ddelay(1);
dvb_delay(1);
#endif
if ((jiffies - start) > ARM_WAIT_FREE) {
printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
......@@ -1269,7 +1296,7 @@ static int CommandRequest(av7110_t *av7110, u16 *Buff, int length, u16 *buf, int
#ifndef _NOHANDSHAKE
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) {
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_SHAKE) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
up(&av7110->dcomlock);
......@@ -1301,7 +1328,7 @@ static int CommandRequest(av7110_t *av7110, u16 *Buff, int length, u16 *buf, int
static inline int
RequestParameter(av7110_t *av7110, u16 tag, u16* Buff, s16 length)
RequestParameter(struct av7110 *av7110, u16 tag, u16* Buff, s16 length)
{
int ret;
ret = CommandRequest(av7110, &tag, 0, Buff, length);
......@@ -1315,9 +1342,22 @@ RequestParameter(av7110_t *av7110, u16 tag, u16* Buff, s16 length)
* Firmware commands
****************************************************************************/
static inline int
msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
{
u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff };
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
struct i2c_msg msgs;
msgs.flags=0;
msgs.addr=0x40;
msgs.len=5;
msgs.buf=msg;
return i2c->xfer(i2c, &msgs, 1);
}
inline static int
SendDAC(av7110_t *av7110, u8 addr, u8 data)
SendDAC(struct av7110 *av7110, u8 addr, u8 data)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -1325,9 +1365,9 @@ SendDAC(av7110_t *av7110, u8 addr, u8 data)
}
static int
SetVolume(av7110_t *av7110, int volleft, int volright)
SetVolume(struct av7110 *av7110, int volleft, int volright)
{
int err;
int err, vol, val, balance = 0;
DEB_EE(("av7110: %p\n",av7110));
......@@ -1349,54 +1389,65 @@ SetVolume(av7110_t *av7110, int volleft, int volright)
i2c_writereg(av7110, 0x20, 0x03, volleft);
i2c_writereg(av7110, 0x20, 0x04, volright);
return 0;
case DVB_ADAC_MSP:
vol = (volleft > volright) ? volleft : volright;
val = (vol * 0x73 / 255) << 8;
if (vol > 0) {
balance = ((volright-volleft) * 127) / vol;
}
msp_writereg(av7110, 0x12, 0x0001, balance << 8);
msp_writereg(av7110, 0x12, 0x0000, val); /* loudspeaker */
msp_writereg(av7110, 0x12, 0x0006, val); /* headphonesr */
return 0;
}
return 0;
}
#ifdef CONFIG_DVB_AV7110_OSD
inline static int ResetBlend(av7110_t *av7110, u8 windownr)
inline static int ResetBlend(struct av7110 *av7110, u8 windownr)
{
return outcom(av7110, COMTYPE_OSD, SetNonBlend, 1, windownr);
}
inline static int SetColorBlend(av7110_t *av7110, u8 windownr)
inline static int SetColorBlend(struct av7110 *av7110, u8 windownr)
{
return outcom(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
}
inline static int SetWindowBlend(av7110_t *av7110, u8 windownr, u8 blending)
inline static int SetWindowBlend(struct av7110 *av7110, u8 windownr, u8 blending)
{
return outcom(av7110, COMTYPE_OSD, SetWBlend, 2, windownr, blending);
}
inline static int SetBlend_(av7110_t *av7110, u8 windownr,
OSDPALTYPE colordepth, u16 index, u8 blending)
inline static int SetBlend_(struct av7110 *av7110, u8 windownr,
enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
{
return outcom(av7110, COMTYPE_OSD, SetBlend, 4,
windownr, colordepth, index, blending);
}
inline static int SetColor_(av7110_t *av7110, u8 windownr,
OSDPALTYPE colordepth, u16 index, u16 colorhi, u16 colorlo)
inline static int SetColor_(struct av7110 *av7110, u8 windownr,
enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
{
return outcom(av7110, COMTYPE_OSD, SetColor, 5,
windownr, colordepth, index, colorhi, colorlo);
}
inline static int BringToTop(av7110_t *av7110, u8 windownr)
inline static int BringToTop(struct av7110 *av7110, u8 windownr)
{
return outcom(av7110, COMTYPE_OSD, WTop, 1, windownr);
}
inline static int SetFont(av7110_t *av7110, u8 windownr, u8 fontsize,
inline static int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
u16 colorfg, u16 colorbg)
{
return outcom(av7110, COMTYPE_OSD, Set_Font, 4,
windownr, fontsize, colorfg, colorbg);
}
static int FlushText(av7110_t *av7110)
static int FlushText(struct av7110 *av7110)
{
u32 start;
......@@ -1404,7 +1455,7 @@ static int FlushText(av7110_t *av7110)
return -ERESTARTSYS;
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) {
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_OSD) {
printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__);
up(&av7110->dcomlock);
......@@ -1415,7 +1466,7 @@ static int FlushText(av7110_t *av7110)
return 0;
}
static int WriteText(av7110_t *av7110, u8 win, u16 x, u16 y, u8* buf)
static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
{
int i, ret;
u32 start;
......@@ -1427,7 +1478,7 @@ static int WriteText(av7110_t *av7110, u8 win, u16 x, u16 y, u8* buf)
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) {
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_OSD) {
printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__);
up(&av7110->dcomlock);
......@@ -1437,7 +1488,7 @@ static int WriteText(av7110_t *av7110, u8 win, u16 x, u16 y, u8* buf)
#ifndef _NOHANDSHAKE
start = jiffies;
while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) {
ddelay(1);
dvb_delay(1);
if ((jiffies - start) > ARM_WAIT_SHAKE) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
up(&av7110->dcomlock);
......@@ -1457,42 +1508,42 @@ static int WriteText(av7110_t *av7110, u8 win, u16 x, u16 y, u8* buf)
return ret;
}
inline static int DrawLine(av7110_t *av7110, u8 windownr,
inline static int DrawLine(struct av7110 *av7110, u8 windownr,
u16 x, u16 y, u16 dx, u16 dy, u16 color)
{
return outcom(av7110, COMTYPE_OSD, DLine, 6,
windownr, x, y, dx, dy, color);
}
inline static int DrawBlock(av7110_t *av7110, u8 windownr,
inline static int DrawBlock(struct av7110 *av7110, u8 windownr,
u16 x, u16 y, u16 dx, u16 dy, u16 color)
{
return outcom(av7110, COMTYPE_OSD, DBox, 6,
windownr, x, y, dx, dy, color);
}
inline static int HideWindow(av7110_t *av7110, u8 windownr)
inline static int HideWindow(struct av7110 *av7110, u8 windownr)
{
return outcom(av7110, COMTYPE_OSD, WHide, 1, windownr);
}
inline static int MoveWindowRel(av7110_t *av7110, u8 windownr, u16 x, u16 y)
inline static int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
{
return outcom(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
}
inline static int MoveWindowAbs(av7110_t *av7110, u8 windownr, u16 x, u16 y)
inline static int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
{
return outcom(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
}
inline static int DestroyOSDWindow(av7110_t *av7110, u8 windownr)
inline static int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
{
return outcom(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
}
#if 0
static void DestroyOSDWindows(av7110_t *av7110)
static void DestroyOSDWindows(struct av7110 *av7110)
{
int i;
......@@ -1502,19 +1553,19 @@ static void DestroyOSDWindows(av7110_t *av7110)
#endif
static inline int
CreateOSDWindow(av7110_t *av7110, u8 windownr,
DISPTYPE disptype, u16 width, u16 height)
CreateOSDWindow(struct av7110 *av7110, u8 windownr,
enum av7110_window_display_type disptype, u16 width, u16 height)
{
return outcom(av7110, COMTYPE_OSD, WCreate, 4,
windownr, disptype, width, height);
}
static OSDPALTYPE bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit};
static DISPTYPE bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8};
static enum av7110_osd_palette_type bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit};
static enum av7110_window_display_type bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8};
static inline int
LoadBitmap(av7110_t *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data)
LoadBitmap(struct av7110 *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data)
{
int bpp;
int i;
......@@ -1533,7 +1584,7 @@ LoadBitmap(av7110_t *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data)
break;
schedule();
}
current->state=TASK_RUNNING;
set_current_state(TASK_RUNNING);
remove_wait_queue(&av7110->bmpq, &wait);
}
if (av7110->bmp_state==BMP_LOADING)
......@@ -1574,7 +1625,7 @@ LoadBitmap(av7110_t *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data)
}
static int
BlitBitmap(av7110_t *av7110, u16 win, u16 x, u16 y, u16 trans)
BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
{
DECLARE_WAITQUEUE(wait, current);
......@@ -1591,7 +1642,7 @@ BlitBitmap(av7110_t *av7110, u16 win, u16 x, u16 y, u16 trans)
break;
schedule();
}
current->state=TASK_RUNNING;
set_current_state(TASK_RUNNING);
remove_wait_queue(&av7110->bmpq, &wait);
}
if (av7110->bmp_state==BMP_LOADED)
......@@ -1600,7 +1651,7 @@ BlitBitmap(av7110_t *av7110, u16 win, u16 x, u16 y, u16 trans)
}
static inline int
ReleaseBitmap(av7110_t *av7110)
ReleaseBitmap(struct av7110 *av7110)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -1627,7 +1678,7 @@ static u32 RGB2YUV(u16 R, u16 G, u16 B)
}
static void
OSDSetColor(av7110_t *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
{
u16 ch, cl;
u32 yuv;
......@@ -1642,7 +1693,7 @@ OSDSetColor(av7110_t *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
}
static int
OSDSetBlock(av7110_t *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data)
OSDSetBlock(struct av7110 *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data)
{
uint w, h, bpp, bpl, size, lpb, bnum, brest;
int i;
......@@ -1673,7 +1724,7 @@ OSDSetBlock(av7110_t *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data)
}
static int
OSD_DrawCommand(av7110_t *av7110, osd_cmd_t *dc)
OSD_DrawCommand(struct av7110 *av7110, osd_cmd_t *dc)
{
switch (dc->cmd) {
case OSD_Close:
......@@ -1784,7 +1835,7 @@ dvb_osd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -1816,7 +1867,7 @@ static struct dvb_device dvbdev_osd = {
/* get version of the firmware ROM, RTSL, video ucode and ARM application */
static void
firmversion(av7110_t *av7110)
firmversion(struct av7110 *av7110)
{
u16 buf[20];
......@@ -1837,7 +1888,7 @@ firmversion(av7110_t *av7110)
av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
/* print firmware capabilities */
if ((av7110->arm_app >> 16) & 0x8000)
if (FW_CI_LL_SUPPORT(av7110->arm_app))
printk ("DVB: AV711%d(%d) - firmware supports CI link layer interface\n",
av7110->avtype, av7110->dvb_adapter->num);
else
......@@ -1848,7 +1899,7 @@ firmversion(av7110_t *av7110)
}
static int
waitdebi(av7110_t *av7110, int adr, int state)
waitdebi(struct av7110 *av7110, int adr, int state)
{
int k;
......@@ -1863,7 +1914,7 @@ waitdebi(av7110_t *av7110, int adr, int state)
static int
load_dram(av7110_t *av7110, u32 *data, int len)
load_dram(struct av7110 *av7110, u32 *data, int len)
{
int i;
int blocks, rest;
......@@ -1939,7 +1990,7 @@ bootcode[] = {
#include "av7110_firm.h"
static int
bootarm(av7110_t *av7110)
bootarm(struct av7110 *av7110)
{
struct saa7146_dev *dev= av7110->dev;
u32 ret;
......@@ -1986,7 +2037,7 @@ bootarm(av7110_t *av7110)
wait_for_debi_done(av7110);
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
current->state=TASK_INTERRUPTIBLE;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
DEB_D(("bootarm: load dram code\n"));
......@@ -2019,21 +2070,26 @@ bootarm(av7110_t *av7110)
}
static inline int
SetPIDs(av7110_t *av7110, u16 vpid, u16 apid, u16 ttpid,
SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
DEB_EE(("av7110: %p\n",av7110));
if (vpid == 0x1fff || apid == 0x1fff ||
ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff)
ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
vpid = apid = ttpid = subpid = pcrpid = 0;
av7110->pids[DMX_PES_VIDEO] = 0;
av7110->pids[DMX_PES_AUDIO] = 0;
av7110->pids[DMX_PES_TELETEXT] = 0;
av7110->pids[DMX_PES_PCR] = 0;
}
return outcom(av7110, COMTYPE_PIDFILTER, MultiPID, 5,
pcrpid, vpid, apid, ttpid, subpid);
}
static void
ChangePIDs(av7110_t *av7110, u16 vpid, u16 apid, u16 ttpid,
ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -2048,15 +2104,17 @@ ChangePIDs(av7110_t *av7110, u16 vpid, u16 apid, u16 ttpid,
av7110->pids[DMX_PES_SUBTITLE]=0;
if (av7110->fe_synced)
if (av7110->fe_synced) {
pcrpid = av7110->pids[DMX_PES_PCR];
SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
}
up(&av7110->pid_mutex);
}
static void
SetMode(av7110_t *av7110, int mode)
SetMode(struct av7110 *av7110, int mode)
{
DEB_EE(("av7110: %p\n",av7110));
......@@ -2072,14 +2130,14 @@ SetMode(av7110_t *av7110, int mode)
}
inline static void
TestMode(av7110_t *av7110, int mode)
TestMode(struct av7110 *av7110, int mode)
{
DEB_EE(("av7110: %p\n",av7110));
outcom(av7110, COMTYPE_ENCODER, SetTestMode, 1, mode);
}
inline static void
VidMode(av7110_t *av7110, int mode)
VidMode(struct av7110 *av7110, int mode)
{
DEB_EE(("av7110: %p\n",av7110));
outcom(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
......@@ -2087,7 +2145,7 @@ VidMode(av7110_t *av7110, int mode)
static int inline
vidcom(av7110_t *av7110, u32 com, u32 arg)
vidcom(struct av7110 *av7110, u32 com, u32 arg)
{
DEB_EE(("av7110: %p\n",av7110));
return outcom(av7110, 0x80, 0x02, 4,
......@@ -2096,7 +2154,7 @@ vidcom(av7110_t *av7110, u32 com, u32 arg)
}
static int inline
audcom(av7110_t *av7110, u32 com)
audcom(struct av7110 *av7110, u32 com)
{
DEB_EE(("av7110: %p\n",av7110));
return outcom(av7110, 0x80, 0x03, 4,
......@@ -2104,7 +2162,7 @@ audcom(av7110_t *av7110, u32 com)
}
inline static void
Set22K(av7110_t *av7110, int state)
Set22K(struct av7110 *av7110, int state)
{
DEB_EE(("av7110: %p\n",av7110));
outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
......@@ -2112,7 +2170,7 @@ Set22K(av7110_t *av7110, int state)
static
int SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst)
int SendDiSEqCMsg(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
{
int i;
u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
......@@ -2145,7 +2203,7 @@ int SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst)
****************************************************************************/
static inline int
i2c_writereg(av7110_t *av7110, u8 id, u8 reg, u8 val)
i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
{
u8 msg[2]={ reg, val };
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
......@@ -2158,22 +2216,8 @@ i2c_writereg(av7110_t *av7110, u8 id, u8 reg, u8 val)
return i2c->xfer (i2c, &msgs, 1);
}
static inline int
msp_writereg(av7110_t *av7110, u8 dev, u16 reg, u16 val)
{
u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff };
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
struct i2c_msg msgs;
msgs.flags=0;
msgs.addr=0x40;
msgs.len=5;
msgs.buf=msg;
return i2c->xfer(i2c, &msgs, 1);
}
static inline u8
i2c_readreg(av7110_t *av7110, u8 id, u8 reg)
i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
{
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
u8 mm1[] = {0x00};
......@@ -2204,7 +2248,7 @@ static int sw2mode[16] = {
};
static void
get_video_format(av7110_t *av7110, u8 *buf, int count)
get_video_format(struct av7110 *av7110, u8 *buf, int count)
{
int i;
int hsize,vsize;
......@@ -2231,7 +2275,7 @@ get_video_format(av7110_t *av7110, u8 *buf, int count)
}
static inline long
aux_ring_buffer_write(dvb_ringbuffer_t *rbuf, const char *buf, unsigned long count)
aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, const char *buf, unsigned long count)
{
unsigned long todo = count;
int free;
......@@ -2256,7 +2300,7 @@ aux_ring_buffer_write(dvb_ringbuffer_t *rbuf, const char *buf, unsigned long cou
static void
play_video_cb(u8 *buf, int count, void *priv)
{
av7110_t *av7110=(av7110_t *) priv;
struct av7110 *av7110=(struct av7110 *) priv;
DEB_EE(("av7110: %p\n",av7110));
if ((buf[3]&0xe0)==0xe0) {
......@@ -2269,7 +2313,7 @@ play_video_cb(u8 *buf, int count, void *priv)
static void
play_audio_cb(u8 *buf, int count, void *priv)
{
av7110_t *av7110=(av7110_t *) priv;
struct av7110 *av7110=(struct av7110 *) priv;
DEB_EE(("av7110: %p\n",av7110));
aux_ring_buffer_write(&av7110->aout, buf, count);
......@@ -2278,7 +2322,7 @@ play_audio_cb(u8 *buf, int count, void *priv)
#define FREE_COND (dvb_ringbuffer_free(&av7110->avout)>=20*1024 && dvb_ringbuffer_free(&av7110->aout)>=20*1024)
static ssize_t
dvb_play(av7110_t *av7110, const u8 *buf,
dvb_play(struct av7110 *av7110, const u8 *buf,
unsigned long count, int nonblock, int type, int umem)
{
unsigned long todo = count, n;
......@@ -2317,7 +2361,7 @@ dvb_play(av7110_t *av7110, const u8 *buf,
}
static ssize_t
dvb_aplay(av7110_t *av7110, const u8 *buf,
dvb_aplay(struct av7110 *av7110, const u8 *buf,
unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
......@@ -2351,7 +2395,7 @@ dvb_aplay(av7110_t *av7110, const u8 *buf,
return count-todo;
}
void init_p2t(p2t_t *p, struct dvb_demux_feed *feed)
void init_p2t(struct av7110_p2t *p, struct dvb_demux_feed *feed)
{
memset(p->pes,0,TS_SIZE);
p->counter = 0;
......@@ -2360,7 +2404,7 @@ void init_p2t(p2t_t *p, struct dvb_demux_feed *feed)
if (feed) p->feed = feed;
}
void clear_p2t(p2t_t *p)
void clear_p2t(struct av7110_p2t *p)
{
memset(p->pes,0,TS_SIZE);
// p->counter = 0;
......@@ -2414,7 +2458,7 @@ long int find_pes_header(u8 const *buf, long int length, int *frags)
return c;
}
void pes_to_ts( u8 const *buf, long int length, u16 pid, p2t_t *p)
void pes_to_ts( u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
{
int c,c2,l,add;
int check,rest;
......@@ -2638,7 +2682,7 @@ static
unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
{
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
av7110_t *av7110 = (av7110_t *) dvbdev->priv;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
unsigned int mask = 0;
DEB_EE(("av7110: %p\n",av7110));
......@@ -2673,7 +2717,7 @@ static int
StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{
struct dvb_demux_feed *dvbdmxfeed=dvbdmxfilter->feed;
av7110_t *av7110=(av7110_t *) dvbdmxfeed->demux->priv;
struct av7110 *av7110=(struct av7110 *) dvbdmxfeed->demux->priv;
u16 buf[20];
int ret, i;
u16 handle;
......@@ -2716,7 +2760,7 @@ StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
static int
StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{
av7110_t *av7110=(av7110_t *) dvbdmxfilter->feed->demux->priv;
struct av7110 *av7110=(struct av7110 *) dvbdmxfilter->feed->demux->priv;
u16 buf[3];
u16 answ[2];
int ret;
......@@ -2753,8 +2797,8 @@ static int
av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
{
struct dvb_demux *demux = feed->demux;
av7110_t *av7110 = (av7110_t *) demux->priv;
ipack *ipack = &av7110->ipack[feed->pes_type];
struct av7110 *av7110 = (struct av7110 *) demux->priv;
struct ipack *ipack = &av7110->ipack[feed->pes_type];
DEB_EE(("av7110: %p\n",av7110));
......@@ -2793,7 +2837,7 @@ static void
dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
struct av7110 *av7110=(struct av7110 *) dvbdmx->priv;
u16 *pid=dvbdmx->pids, npids[5];
int i;
......@@ -2809,7 +2853,7 @@ dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
StartHWFilter(dvbdmxfeed->filter);
return;
}
if (dvbdmxfeed->pes_type<=2)
if (dvbdmxfeed->pes_type<=2 || dvbdmxfeed->pes_type==4)
ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
if (dvbdmxfeed->pes_type<2 && npids[0])
......@@ -2832,7 +2876,7 @@ static void
dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
struct av7110 *av7110=(struct av7110 *) dvbdmx->priv;
u16 *pid=dvbdmx->pids, npids[5];
int i;
......@@ -2870,7 +2914,7 @@ static int
av7110_start_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
av7110_t *av7110 = (av7110_t *) demux->priv;
struct av7110 *av7110 = (struct av7110 *) demux->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -2929,7 +2973,7 @@ static int
av7110_stop_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
av7110_t *av7110 = (av7110_t *) demux->priv;
struct av7110 *av7110 = (struct av7110 *) demux->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -2967,7 +3011,7 @@ av7110_stop_feed(struct dvb_demux_feed *feed)
static void
restart_feeds(av7110_t *av7110)
restart_feeds(struct av7110 *av7110)
{
struct dvb_demux *dvbdmx=&av7110->demux;
struct dvb_demux_feed *feed;
......@@ -2990,6 +3034,46 @@ restart_feeds(av7110_t *av7110)
AV_StartPlay(av7110, mode);
}
static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
uint64_t *stc, unsigned int *base)
{
int ret;
u16 fwstc[4];
u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
struct dvb_demux *dvbdemux;
struct av7110 *av7110;
/* pointer casting paranoia... */
if (!demux)
BUG();
dvbdemux = (struct dvb_demux *) demux->priv;
if (!dvbdemux)
BUG();
av7110 = (struct av7110 *) dvbdemux->priv;
DEB_EE(("av7110: %p\n",av7110));
if (num != 0)
return -EINVAL;
ret = CommandRequest(av7110, &tag, 0, fwstc, 4);
if (ret) {
printk(KERN_ERR "%s: CommandRequest error\n", __FUNCTION__);
return -EIO;
}
DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n",
fwstc[0], fwstc[1], fwstc[2], fwstc[3]));
*stc = (((uint64_t)fwstc[2] & 1) << 32) |
(((uint64_t)fwstc[1]) << 16) | ((uint64_t)fwstc[0]);
*base = 1;
DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc));
return 0;
}
/******************************************************************************
* SEC device file operations
******************************************************************************/
......@@ -2997,7 +3081,7 @@ restart_feeds(av7110_t *av7110)
static
int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
av7110_t *av7110 = fe->before_after_data;
struct av7110 *av7110 = fe->before_after_data;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3018,13 +3102,12 @@ int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
case FE_DISEQC_SEND_MASTER_CMD:
{
struct dvb_diseqc_master_cmd *cmd = arg;
SendDiSEqCMsg (av7110, cmd->msg_len, cmd->msg, 0);
SendDiSEqCMsg (av7110, cmd->msg_len, cmd->msg, -1);
break;
}
case FE_DISEQC_SEND_BURST:
SendDiSEqCMsg (av7110, 0, NULL, (int) arg);
SendDiSEqCMsg (av7110, 0, NULL, (unsigned long)arg);
break;
default:
......@@ -3038,20 +3121,20 @@ int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
* CI link layer file ops (FIXME: move this to separate module later)
******************************************************************************/
int ci_ll_init(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf, int size)
int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size)
{
dvb_ringbuffer_init(cirbuf, vmalloc(size), size);
dvb_ringbuffer_init(ciwbuf, vmalloc(size), size);
return 0;
}
void ci_ll_flush(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf)
void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
{
dvb_ringbuffer_flush_spinlock_wakeup(cirbuf);
dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf);
}
void ci_ll_release(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf)
void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
{
vfree(cirbuf->data);
cirbuf->data=0;
......@@ -3060,7 +3143,7 @@ void ci_ll_release(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf)
}
int ci_ll_reset(dvb_ringbuffer_t *cibuf, struct file *file,
int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file,
int slots, ca_slot_info_t *slot)
{
int i;
......@@ -3087,7 +3170,7 @@ int ci_ll_reset(dvb_ringbuffer_t *cibuf, struct file *file,
}
static ssize_t
ci_ll_write(dvb_ringbuffer_t *cibuf, struct file *file, const char *buf, size_t count, loff_t *ppos)
ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, const char *buf, size_t count, loff_t *ppos)
{
int free;
int non_blocking=file->f_flags&O_NONBLOCK;
......@@ -3110,7 +3193,7 @@ ci_ll_write(dvb_ringbuffer_t *cibuf, struct file *file, const char *buf, size_t
}
static ssize_t
ci_ll_read(dvb_ringbuffer_t *cibuf, struct file *file, char *buf, size_t count, loff_t *ppos)
ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, char *buf, size_t count, loff_t *ppos)
{
int avail;
int non_blocking=file->f_flags&O_NONBLOCK;
......@@ -3139,7 +3222,7 @@ static int
dvb_ca_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
int err=dvb_generic_open(inode, file);
DEB_EE(("av7110: %p\n",av7110));
......@@ -3154,9 +3237,9 @@ static
unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
{
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
av7110_t *av7110 = (av7110_t *) dvbdev->priv;
dvb_ringbuffer_t *rbuf = &av7110->ci_rbuffer;
dvb_ringbuffer_t *wbuf = &av7110->ci_wbuffer;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
unsigned int mask = 0;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3177,7 +3260,7 @@ int dvb_ca_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
unsigned long arg=(unsigned long) parg;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3196,7 +3279,7 @@ int dvb_ca_ioctl(struct inode *inode, struct file *file,
cap.slot_num=2;
#ifdef NEW_CI
cap.slot_type=CA_CI_LINK|CA_DESCR;
cap.slot_type=(FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI) | CA_DESCR;
#else
cap.slot_type=CA_CI|CA_DESCR;
#endif
......@@ -3214,7 +3297,7 @@ int dvb_ca_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
av7110->ci_slot[info->num].num = info->num;
#ifdef NEW_CI
av7110->ci_slot[info->num].type = CA_CI_LINK;
av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI;
#else
av7110->ci_slot[info->num].type = CA_CI;
#endif
......@@ -3266,7 +3349,7 @@ dvb_ca_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
......@@ -3276,7 +3359,7 @@ static ssize_t
dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
......@@ -3284,6 +3367,74 @@ dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos)
/******************************************************************************
* Video MPEG decoder events
******************************************************************************/
static
void dvb_video_add_event (struct av7110 *av7110, struct video_event *event)
{
struct dvb_video_events *events = &av7110->video_events;
int wp;
DEB_D(("\n"));
spin_lock_bh(&events->lock);
wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
if (wp == events->eventr) {
events->overflow = 1;
events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
}
//FIXME: timestamp?
memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
events->eventw = wp;
spin_unlock_bh(&events->lock);
wake_up_interruptible (&events->wait_queue);
}
static
int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
{
struct dvb_video_events *events = &av7110->video_events;
DEB_D(("\n"));
if (events->overflow) {
events->overflow = 0;
return -EOVERFLOW;
}
if (events->eventw == events->eventr) {
int ret;
if (flags & O_NONBLOCK)
return -EWOULDBLOCK;
ret = wait_event_interruptible (events->wait_queue,
events->eventw != events->eventr);
if (ret < 0)
return ret;
}
spin_lock_bh(&events->lock);
memcpy (event, &events->events[events->eventr],
sizeof(struct video_event));
events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
spin_unlock_bh(&events->lock);
return 0;
}
/******************************************************************************
* DVB device file operations
******************************************************************************/
......@@ -3292,18 +3443,22 @@ static
unsigned int dvb_video_poll(struct file *file, poll_table *wait)
{
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
av7110_t *av7110 = (av7110_t *) dvbdev->priv;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
unsigned int mask = 0;
DEB_EE(("av7110: %p\n",av7110));
poll_wait(file, &av7110->avout.queue, wait);
poll_wait(file, &av7110->video_events.wait_queue, wait);
if (av7110->video_events.eventw != av7110->video_events.eventr)
mask = POLLPRI;
if (av7110->playing) {
if (FREE_COND)
mask |= (POLLOUT | POLLWRNORM);
} else /* if not playing: may play if asked for */
mask = (POLLOUT | POLLWRNORM);
mask |= (POLLOUT | POLLWRNORM);
return mask;
}
......@@ -3313,7 +3468,7 @@ dvb_video_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3328,7 +3483,7 @@ dvb_audio_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3343,24 +3498,27 @@ u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
#define MIN_IFRAME 400000
static void
play_iframe(av7110_t *av7110, u8 *buf, unsigned int len, int nonblock)
static int
play_iframe(struct av7110 *av7110, u8 *buf, unsigned int len, int nonblock)
{
int i, n=1;
DEB_EE(("av7110: %p\n",av7110));
if (!(av7110->playing&RP_VIDEO)) {
AV_StartPlay(av7110, RP_VIDEO);
if (AV_StartPlay(av7110, RP_VIDEO) < 0)
return -EBUSY;
n=MIN_IFRAME/len+1;
}
/* FIXME: nonblock? */
dvb_play(av7110, iframe_header, sizeof(iframe_header), 0, 1, 0);
for (i=0; i<n; i++)
dvb_play(av7110, buf, len, 0, 1, 1);
av7110_ipack_flush(&av7110->ipack[1]);
return 0;
}
......@@ -3369,7 +3527,7 @@ dvb_video_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
unsigned long arg=(unsigned long) parg;
int ret=0;
......@@ -3441,8 +3599,12 @@ dvb_video_ioctl(struct inode *inode, struct file *file,
break;
case VIDEO_GET_EVENT:
//FIXME: write firmware support for this
ret=-EOPNOTSUPP;
ret=dvb_video_get_event(av7110, parg, file->f_flags);
break;
case VIDEO_GET_SIZE:
memcpy(parg, &av7110->video_size, sizeof(video_size_t));
break;
case VIDEO_SET_DISPLAY_FORMAT:
{
......@@ -3488,8 +3650,9 @@ dvb_video_ioctl(struct inode *inode, struct file *file,
{
struct video_still_picture *pic=
(struct video_still_picture *) parg;
av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
play_iframe(av7110, pic->iFrame, pic->size,
ret = play_iframe(av7110, pic->iFrame, pic->size,
file->f_flags&O_NONBLOCK);
break;
}
......@@ -3560,7 +3723,7 @@ dvb_audio_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
unsigned long arg=(unsigned long) parg;
int ret=0;
......@@ -3680,7 +3843,7 @@ dvb_audio_ioctl(struct inode *inode, struct file *file,
static int dvb_video_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
int err;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3692,13 +3855,18 @@ static int dvb_video_open(struct inode *inode, struct file *file)
av7110->video_blank=1;
av7110->audiostate.AV_sync_state=1;
av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX;
if ((file->f_flags & O_ACCMODE) != O_RDONLY)
/* empty event queue */
av7110->video_events.eventr = av7110->video_events.eventw = 0;
return 0;
}
static int dvb_video_release(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3709,7 +3877,7 @@ static int dvb_video_release(struct inode *inode, struct file *file)
static int dvb_audio_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
int err=dvb_generic_open(inode, file);
DEB_EE(("av7110: %p\n",av7110));
......@@ -3724,7 +3892,7 @@ static int dvb_audio_open(struct inode *inode, struct file *file)
static int dvb_audio_release(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3794,7 +3962,7 @@ static struct dvb_device dvbdev_ca = {
static
void av7110_before_after_tune (fe_status_t s, void *data)
{
struct av7110_s *av7110 = data;
struct av7110 *av7110 = data;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3820,10 +3988,9 @@ void av7110_before_after_tune (fe_status_t s, void *data)
static
int av7110_register(av7110_t *av7110)
int av7110_register(struct av7110 *av7110)
{
int ret, i;
dmx_frontend_t *dvbfront=&av7110->hw_frontend;
struct dvb_demux *dvbdemux=&av7110->demux;
DEB_EE(("av7110: %p\n",av7110));
......@@ -3856,8 +4023,6 @@ int av7110_register(av7110_t *av7110)
av7110->videostate.display_format=VIDEO_CENTER_CUT_OUT;
av7110->display_ar=VIDEO_FORMAT_4_3;
memcpy(av7110->demux_id, "demux0_0", 9);
av7110->demux_id[5] = av7110->dvb_adapter->num + '0';
dvbdemux->priv = (void *) av7110;
for (i=0; i<32; i++)
......@@ -3868,18 +4033,11 @@ int av7110_register(av7110_t *av7110)
dvbdemux->start_feed = av7110_start_feed;
dvbdemux->stop_feed = av7110_stop_feed;
dvbdemux->write_to_decoder = av7110_write_to_decoder;
dvbdemux->dmx.vendor = "TI";
dvbdemux->dmx.model = "AV7110";
dvbdemux->dmx.id = av7110->demux_id;
dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
DMX_MEMORY_BASED_FILTERING);
dvb_dmx_init(&av7110->demux);
dvbfront->id = "hw_frontend";
dvbfront->vendor = "VLSI";
dvbfront->model = "DVB Frontend";
dvbfront->source = DMX_FRONTEND_0;
av7110->demux.dmx.get_stc = dvb_get_stc;
av7110->dmxdev.filternum = 32;
av7110->dmxdev.demux = &dvbdemux->dmx;
......@@ -3887,14 +4045,13 @@ int av7110_register(av7110_t *av7110)
dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
&av7110->hw_frontend);
av7110->hw_frontend.source = DMX_FRONTEND_0;
ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
if (ret < 0)
return ret;
av7110->mem_frontend.id = "mem_frontend";
av7110->mem_frontend.vendor = "memory";
av7110->mem_frontend.model = "sw";
av7110->mem_frontend.source = DMX_MEMORY_FE;
ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
......@@ -3907,6 +4064,12 @@ int av7110_register(av7110_t *av7110)
if (ret < 0)
return ret;
init_waitqueue_head(&av7110->video_events.wait_queue);
spin_lock_init(&av7110->video_events.lock);
av7110->video_events.eventw = av7110->video_events.eventr = 0;
av7110->video_events.overflow = 0;
memset(&av7110->video_size, 0, sizeof (video_size_t));
dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
&dvbdev_video, av7110, DVB_DEVICE_VIDEO);
......@@ -3936,7 +4099,7 @@ int av7110_register(av7110_t *av7110)
static void
dvb_unregister(av7110_t *av7110)
dvb_unregister(struct av7110 *av7110)
{
struct dvb_demux *dvbdemux=&av7110->demux;
......@@ -3991,18 +4154,18 @@ struct saa7146_extension_ioctls ioctls[] = {
static
int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
{
av7110_t *av7110 = NULL;
struct av7110 *av7110 = NULL;
int ret = 0;
if (!(av7110 = kmalloc (sizeof (struct av7110_s), GFP_KERNEL))) {
if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
printk ("%s: out of memory!\n", __FUNCTION__);
return -ENOMEM;
}
memset(av7110, 0, sizeof(av7110_t));
memset(av7110, 0, sizeof(struct av7110));
av7110->card_name = (char*)pci_ext->ext_priv;
(av7110_t*)dev->ext_priv = av7110;
(struct av7110*)dev->ext_priv = av7110;
DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
......@@ -4062,9 +4225,6 @@ int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *p
av7110->debilock=SPIN_LOCK_UNLOCKED;
av7110->debitype=-1;
/* default ADAC type */
av7110->adac_type = adac;
/* default OSD window */
av7110->osdwin=1;
......@@ -4120,30 +4280,32 @@ int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *p
kernel_thread(arm_thread, (void *) av7110, 0);
/* set internal volume control to maximum */
av7110->adac_type = DVB_ADAC_TI;
SetVolume(av7110, 0xff, 0xff);
VidMode(av7110, vidmode);
/* remaining inits according to card and frontend type */
if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) {
printk ("av7110%d: Crystal audio DAC detected\n",
printk ("av7110(%d): Crystal audio DAC detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_CRYSTAL;
i2c_writereg(av7110, 0x20, 0x01, 0xd2);
i2c_writereg(av7110, 0x20, 0x02, 0x49);
i2c_writereg(av7110, 0x20, 0x03, 0x00);
i2c_writereg(av7110, 0x20, 0x04, 0x00);
}
/**
* some special handling for the Siemens DVB-C card...
* some special handling for the Siemens DVB-C cards...
*/
if (dev->pci->subsystem_vendor == 0x110a) {
if (i2c_writereg(av7110, 0x80, 0x0, 0x80)==1) {
} else if (i2c_writereg(av7110, 0x80, 0x0, 0x80)==1) {
i2c_writereg(av7110, 0x80, 0x0, 0);
printk ("av7110: DVB-C analog module detected, "
"initializing MSP3400\n");
ddelay(10);
printk ("av7110(%d): DVB-C analog module detected, "
"initializing MSP3400\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_MSP;
dvb_delay(100);
msp_writereg(av7110, 0x12, 0x0013, 0x0c00);
msp_writereg(av7110, 0x12, 0x0000, 0x7f00); // loudspeaker + headphone
msp_writereg(av7110, 0x12, 0x0008, 0x0220); // loudspeaker source
......@@ -4151,17 +4313,26 @@ int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *p
msp_writereg(av7110, 0x12, 0x000a, 0x0220); // SCART 1 source
msp_writereg(av7110, 0x12, 0x0007, 0x7f00); // SCART 1 volume
msp_writereg(av7110, 0x12, 0x000d, 0x4800); // prescale SCART
} else if (dev->pci->subsystem_vendor == 0x110a) {
printk("av7110(%d): DVB-C w/o analog module detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_NONE;
} else {
av7110->adac_type = adac;
printk("av7110(%d): adac type set to %d\n",
av7110->dvb_adapter->num, av7110->adac_type);
}
if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
// switch DVB SCART on
outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
//saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
//saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
av7110->adac_type = DVB_ADAC_NONE;
}
SetVolume(av7110, 0xff, 0xff);
av7110_setup_irc_config (av7110, 0);
av7110_register(av7110);
......@@ -4188,7 +4359,7 @@ int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *p
static
int av7110_detach (struct saa7146_dev* saa)
{
av7110_t *av7110 = (av7110_t*)saa->ext_priv;
struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
DEB_EE(("av7110: %p\n",av7110));
saa7146_unregister_device(&av7110->vd, saa);
......@@ -4197,7 +4368,7 @@ int av7110_detach (struct saa7146_dev* saa)
wake_up_interruptible(&av7110->arm_wait);
while (av7110->arm_thread)
ddelay(1);
dvb_delay(1);
dvb_unregister(av7110);
......@@ -4229,7 +4400,7 @@ int av7110_detach (struct saa7146_dev* saa)
static
void av7110_irq(struct saa7146_dev* dev, u32 *isr)
{
av7110_t *av7110 = (av7110_t*)dev->ext_priv;
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
......@@ -4280,6 +4451,7 @@ struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0004),
MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0006),
MAKE_EXTENSION_PCI(tt_t, 0x13c2, 0x0008),
MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x1102),
MAKE_EXTENSION_PCI(unkwn1, 0xffc2, 0x0000),
MAKE_EXTENSION_PCI(unkwn2, 0x00a1, 0x00a1),
MAKE_EXTENSION_PCI(nexus, 0x00a1, 0xa1a0),
......@@ -4288,9 +4460,11 @@ struct pci_device_id pci_tbl[] = {
}
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
{
av7110_t *av7110 = (av7110_t*)dev->ext_priv;
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
if (std->id == V4L2_STD_PAL) {
av7110->vidmode = VIDEO_MODE_PAL;
SetMode(av7110, av7110->vidmode);
......
......@@ -40,39 +40,32 @@
#include "dvb_net.h"
#include "dvb_ringbuffer.h"
typedef enum BOOTSTATES
enum av7110_bootstate
{
BOOTSTATE_BUFFER_EMPTY = 0,
BOOTSTATE_BUFFER_FULL = 1,
BOOTSTATE_BOOT_COMPLETE = 2
} BOOTSTATES;
};
typedef enum
enum av7110_type_rec_play_format
{ RP_None,
AudioPES,
AudioMp2,
AudioPCM,
VideoPES,
AV_PES
} TYPE_REC_PLAY_FORMAT;
typedef struct PARAMSTRUCT
{
unsigned int wCommand;
int error;
unsigned long pdwData[100];
} PARAMSTRUCT, *PPARAMSTRUCT;
};
typedef enum OSDPALTYPE
enum av7110_osd_palette_type
{
NoPalet = 0, /* No palette */
Pal1Bit = 2, /* 2 colors for 1 Bit Palette */
Pal2Bit = 4, /* 4 colors for 2 bit palette */
Pal4Bit = 16, /* 16 colors for 4 bit palette */
Pal8Bit = 256 /* 256 colors for 16 bit palette */
} OSDPALTYPE, *POSDPALTYPE;
};
typedef enum {
enum av7110_window_display_type {
BITMAP1, /* 1 bit bitmap */
BITMAP2, /* 2 bit bitmap */
BITMAP4, /* 4 bit bitmap */
......@@ -93,9 +86,9 @@ typedef enum {
VIDEOTDSIZE, /* True Size MPEG Video Display Double Resolution */
VIDEONSIZE, /* Full Size MPEG Video Display */
CURSOR /* Cursor */
} DISPTYPE; /* Window display type */
};
// switch defines
/* switch defines */
#define SB_GPIO 3
#define SB_OFF SAA7146_GPIO_OUTLO //SlowBlank aus (TV-Mode)
#define SB_ON SAA7146_GPIO_INPUT //SlowBlank an (AV-Mode)
......@@ -106,14 +99,13 @@ typedef enum {
#define FB_ON SAA7146_GPIO_OUTHI //FastBlank an (RGB-Mode)
#define FB_LOOP SAA7146_GPIO_INPUT //FastBlank der PC-Grafik durchschleifen
typedef enum VIDEOOUTPUTMODE
enum av7110_video_output_mode
{
NO_OUT = 0, //disable analog Output
CVBS_RGB_OUT = 1,
CVBS_YC_OUT = 2,
YC_OUT = 3
} VIDEOOUTPUTMODE, *PVIDEOOUTPUTMODE;
};
#define GPMQFull 0x0001 //Main Message Queue Full
#define GPMQOver 0x0002 //Main Message Queue Overflow
......@@ -127,9 +119,9 @@ typedef enum VIDEOOUTPUTMODE
#define SECTION_CYCLE 0x02
#define SECTION_CONTINUOS 0x04
#define SECTION_MODE 0x06
#define SECTION_IPMPE 0x0C // bis zu 4k gro_
#define SECTION_HIGH_SPEED 0x1C // vergrv_erter Puffer f|r High Speed Filter
#define DATA_PIPING_FLAG 0x20 // f|r Data Piping Filter
#define SECTION_IPMPE 0x0C // bis zu 4k gro
#define SECTION_HIGH_SPEED 0x1C // vergrerter Puffer fr High Speed Filter
#define DATA_PIPING_FLAG 0x20 // fr Data Piping Filter
#define PBUFSIZE_NONE 0x0000
#define PBUFSIZE_1P 0x0100
......@@ -141,7 +133,7 @@ typedef enum VIDEOOUTPUTMODE
#define PBUFSIZE_16K 0x0700
#define PBUFSIZE_32K 0x0800
typedef enum {
enum av7110_osd_command {
WCreate,
WDestroy,
WMoveD,
......@@ -162,9 +154,9 @@ typedef enum {
ReleaseBmp,
SetWTrans,
SetWNoTrans
} OSDCOM;
};
typedef enum {
enum av7110_pid_command {
MultiPID,
VideoPID,
AudioPID,
......@@ -177,13 +169,13 @@ typedef enum {
Scan,
SetDescr,
SetIR
} PIDCOM;
};
typedef enum {
enum av7110_mpeg_command {
SelAudChannels
} MPEGCOM;
};
typedef enum {
enum av7110_audio_command {
AudioDAC,
CabADAC,
ON22K,
......@@ -192,9 +184,9 @@ typedef enum {
ADSwitch,
SendDiSEqC,
SetRegister
} AUDCOM;
};
typedef enum {
enum av7110_request_command {
AudioState,
AudioBuffState,
VideoState1,
......@@ -203,19 +195,21 @@ typedef enum {
CrashCounter,
ReqVersion,
ReqVCXO,
ReqRegister
} REQCOM;
ReqRegister,
ReqSecFilterError,
ReqSTC
};
typedef enum {
enum av7110_encoder_command {
SetVidMode,
SetTestMode,
LoadVidCode,
SetMonitorType,
SetPanScanType,
SetFreezeMode
} ENC;
};
typedef enum {
enum av7110_rec_play_state {
__Record,
__Stop,
__Play,
......@@ -224,9 +218,9 @@ typedef enum {
__FF_IP,
__Scan_I,
__Continue
} REC_PLAY;
};
typedef enum {
enum av7110_command_type {
COMTYPE_NOCOM,
COMTYPE_PIDFILTER,
COMTYPE_MPEGDECODER,
......@@ -244,17 +238,7 @@ typedef enum {
COMTYPE_VIDEO,
COMTYPE_AUDIO,
COMTYPE_CI_LL,
} COMTYPE;
typedef enum {
AV7110_VIDEO_FREEZE,
AV7110_VIDEO_CONTINUE
} VIDEOCOM;
typedef enum {
DVB_AUDIO_PAUSE,
} AUDIOCOM;
};
#define VID_NONE_PREF 0x00 /* No aspect ration processing preferred */
#define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */
......@@ -275,6 +259,7 @@ typedef enum {
#define DATA_STREAMING 0x0a
#define DATA_CI_GET 0x0b
#define DATA_CI_PUT 0x0c
#define DATA_MPEG_VIDEO_EVENT 0x0d
#define DATA_PES_RECORD 0x10
#define DATA_PES_PLAY 0x11
......@@ -364,14 +349,6 @@ typedef enum {
#define MAX_PLENGTH 0xFFFF
#define MAX_VID_PES 0x1FFF
typedef struct section_s {
int id;
int length;
int found;
u8 payload[4096+3];
} section_t;
#define MY_STATE_PES_START 1
#define MY_STATE_PES_STARTED 2
#define MY_STATE_FULL 4
......@@ -393,64 +370,34 @@ struct dvb_filter {
enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
typedef struct ps_packet_s{
u8 scr[6];
u8 mux_rate[3];
u8 stuff_length;
u8 data[20];
u8 sheader_llength[2];
int sheader_length;
u8 rate_bound[3];
u8 audio_bound;
u8 video_bound;
u8 reserved;
int npes;
int mpeg;
} ps_packet_t;
typedef struct a2p_s{
int type;
int found;
int length;
int headr;
u8 cid;
u8 flags;
u8 abuf[MAX_PLENGTH];
int alength;
u8 vbuf[MAX_PLENGTH];
int vlength;
int plength;
u8 last_av_pts[4];
u8 av_pts[4];
u8 scr[4];
u16 count0;
u16 count1;
u16 pidv;
u16 pida;
u16 countv;
u16 counta;
void *dataA;
void *dataV;
void (*write_cb)(u8 const *buf, long int count,
void *data);
} a2p_t;
typedef struct p2t_s {
struct av7110_p2t {
u8 pes[TS_SIZE];
u8 counter;
long int pos;
int frags;
struct dvb_demux_feed *feed;
} p2t_t;
};
/* video MPEG decoder events: */
/* (code copied from dvb_frontend.c, should maybe be factored out...) */
#define MAX_VIDEO_EVENT 8
struct dvb_video_events {
struct video_event events[MAX_VIDEO_EVENT];
int eventw;
int eventr;
int overflow;
wait_queue_head_t wait_queue;
spinlock_t lock;
};
/* place to store all the necessary device information */
typedef struct av7110_s {
struct av7110 {
/* devices */
struct dvb_device dvb_dev;
dvb_net_t dvb_net;
struct dvb_net dvb_net;
struct video_device vd;
struct saa7146_dev *dev;
......@@ -464,15 +411,16 @@ typedef struct av7110_s {
int adac_type; /* audio DAC type */
#define DVB_ADAC_TI 0
#define DVB_ADAC_CRYSTAL 1
#define DVB_ADAC_MSP 2
#define DVB_ADAC_NONE -1
/* buffers */
void *iobuf; /* memory for all buffers */
dvb_ringbuffer_t avout; /* buffer for video or A/V mux */
struct dvb_ringbuffer avout; /* buffer for video or A/V mux */
#define AVOUTLEN (128*1024)
dvb_ringbuffer_t aout; /* buffer for audio */
struct dvb_ringbuffer aout; /* buffer for audio */
#define AOUTLEN (64*1024)
void *bmpbuf;
#define BMPLEN (8*32768+1024)
......@@ -522,12 +470,11 @@ typedef struct av7110_s {
ca_slot_info_t ci_slot[2];
int vidmode;
dmxdev_t dmxdev;
struct dmxdev dmxdev;
struct dvb_demux demux;
char demux_id[16];
dmx_frontend_t hw_frontend;
dmx_frontend_t mem_frontend;
struct dmx_frontend hw_frontend;
struct dmx_frontend mem_frontend;
int fe_synced;
struct semaphore pid_mutex;
......@@ -543,9 +490,9 @@ typedef struct av7110_s {
struct audio_status audiostate;
struct dvb_demux_filter *handle2filter[32];
p2t_t p2t_filter[MAXFILT];
dvb_filter_pes2ts_t p2t[2];
struct ipack_s ipack[2];
struct av7110_p2t p2t_filter[MAXFILT];
struct dvb_filter_pes2ts p2t[2];
struct ipack ipack[2];
u8 *kbuf[2];
int sinfo;
......@@ -573,8 +520,8 @@ typedef struct av7110_s {
u16 pids[DMX_PES_OTHER];
dvb_ringbuffer_t ci_rbuffer;
dvb_ringbuffer_t ci_wbuffer;
struct dvb_ringbuffer ci_rbuffer;
struct dvb_ringbuffer ci_wbuffer;
struct dvb_adapter *dvb_adapter;
......@@ -583,8 +530,13 @@ typedef struct av7110_s {
struct dvb_device *ca_dev;
struct dvb_device *osd_dev;
struct dvb_video_events video_events;
video_size_t video_size;
int dsp_dev;
} av7110_t;
u32 ir_config;
};
#define DPRAM_BASE 0x4000
......@@ -623,26 +575,15 @@ typedef struct av7110_s {
#define Reserved (DPRAM_BASE + 0x1E00)
#define Reserved_SIZE 0x1C0
#define DEBUG_WINDOW (DPRAM_BASE + 0x1FC0)
#define DBG_LOOP_CNT (DEBUG_WINDOW + 0x00)
#define DBG_SEC_CNT (DEBUG_WINDOW + 0x02)
#define DBG_AVRP_BUFF (DEBUG_WINDOW + 0x04)
#define DBG_AVRP_PEAK (DEBUG_WINDOW + 0x06)
#define DBG_MSG_CNT (DEBUG_WINDOW + 0x08)
#define DBG_CODE_REG (DEBUG_WINDOW + 0x0a)
#define DBG_TTX_Q (DEBUG_WINDOW + 0x0c)
#define DBG_AUD_EN (DEBUG_WINDOW + 0x0e)
#define DBG_WRONG_COM (DEBUG_WINDOW + 0x10)
#define DBG_ARR_OVFL (DEBUG_WINDOW + 0x12)
#define DBG_BUFF_OVFL (DEBUG_WINDOW + 0x14)
#define DBG_OVFL_CNT (DEBUG_WINDOW + 0x16)
#define DBG_SEC_OVFL (DEBUG_WINDOW + 0x18)
#define STATUS_BASE (DPRAM_BASE + 0x1FC0)
#define STATUS_SCR (STATUS_BASE + 0x00)
#define STATUS_MODES (STATUS_BASE + 0x04)
#define STATUS_LOOPS (STATUS_BASE + 0x08)
#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C)
/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */
#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E)
#define RX_TYPE (DPRAM_BASE + 0x1FE8)
#define RX_LEN (DPRAM_BASE + 0x1FEA)
#define TX_TYPE (DPRAM_BASE + 0x1FEC)
......@@ -673,7 +614,7 @@ extern int av7110_dpram_len, av7110_root_len;
extern void av7110_register_irc_handler(void (*func)(u32));
extern void av7110_unregister_irc_handler(void (*func)(u32));
extern void av7110_setup_irc_config (av7110_t *av7110, u32 ir_config);
extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
extern int av7110_ir_init (void);
extern void av7110_ir_exit (void);
......
#include "dvb_filter.h"
#include "av7110_ipack.h"
#include <linux/string.h> /* for memcpy() */
#include <linux/vmalloc.h>
void av7110_ipack_reset(ipack *p)
void av7110_ipack_reset(struct ipack *p)
{
p->found = 0;
p->cid = 0;
......@@ -19,7 +20,7 @@ void av7110_ipack_reset(ipack *p)
}
void av7110_ipack_init(ipack *p, int size,
void av7110_ipack_init(struct ipack *p, int size,
void (*func)(u8 *buf, int size, void *priv))
{
if ( !(p->buf = vmalloc(size*sizeof(u8))) ){
......@@ -32,17 +33,18 @@ void av7110_ipack_init(ipack *p, int size,
}
void av7110_ipack_free(ipack * p)
void av7110_ipack_free(struct ipack * p)
{
if (p->buf) vfree(p->buf);
if (p->buf)
vfree(p->buf);
}
static
void send_ipack(ipack *p)
void send_ipack(struct ipack *p)
{
int off;
AudioInfo ai;
struct dvb_audio_info ai;
int ac3_off = 0;
int streamid=0;
int nframes= 0;
......@@ -109,7 +111,7 @@ void send_ipack(ipack *p)
}
void av7110_ipack_flush(ipack *p)
void av7110_ipack_flush(struct ipack *p)
{
if (p->plength != MMAX_PLENGTH-6 || p->found<=6)
return;
......@@ -121,7 +123,7 @@ void av7110_ipack_flush(ipack *p)
static
void write_ipack(ipack *p, const u8 *data, int count)
void write_ipack(struct ipack *p, const u8 *data, int count)
{
u8 headr[3] = { 0x00, 0x00, 0x01} ;
......@@ -144,7 +146,7 @@ void write_ipack(ipack *p, const u8 *data, int count)
}
int av7110_ipack_instant_repack (const u8 *buf, int count, ipack *p)
int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
{
int l;
int c=0;
......
#ifndef _AV7110_IPACK_H_
#define _AV7110_IPACK_H_
extern void av7110_ipack_init(ipack *p, int size,
extern void av7110_ipack_init(struct ipack *p, int size,
void (*func)(u8 *buf, int size, void *priv));
extern void av7110_ipack_reset(ipack *p);
extern int av7110_ipack_instant_repack(const u8 *buf, int count, ipack *p);
extern void av7110_ipack_free(ipack * p);
extern void av7110_ipack_flush(ipack *p);
extern void av7110_ipack_reset(struct ipack *p);
extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
extern void av7110_ipack_free(struct ipack * p);
extern void av7110_ipack_flush(struct ipack *p);
#endif
......@@ -7,12 +7,7 @@
#include "av7110.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "input_fake.h"
#endif
#define UP_TIMEOUT (HZ/2)
#define UP_TIMEOUT (HZ/4)
static int av7110_ir_debug = 0;
......@@ -21,11 +16,12 @@ static int av7110_ir_debug = 0;
static struct input_dev input_dev;
static u32 ir_config;
static
u16 key_map [256] = {
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
KEY_8, KEY_9, KEY_MHP, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
......@@ -64,32 +60,61 @@ struct timer_list keyup_timer = { function: av7110_emit_keyup };
static
void av7110_emit_key (u32 ircom)
{
int down = ircom & (0x80000000);
u16 keycode = key_map[ircom & 0xff];
u8 data;
u8 addr;
static u16 old_toggle = 0;
u16 new_toggle;
u16 keycode;
/* extract device address and data */
if (ir_config & 0x0001) {
/* TODO RCMM: ? bits device address, 8 bits data */
data = ircom & 0xff;
addr = (ircom >> 8) & 0xff;
} else {
/* RC5: 5 bits device address, 6 bits data */
data = ircom & 0x3f;
addr = (ircom >> 6) & 0x1f;
}
keycode = key_map[data];
dprintk ("#########%08x######### addr %i data 0x%02x (keycode %i)\n",
ircom, addr, data, keycode);
dprintk ("#########%08x######### key %02x %s (keycode %i)\n",
ircom, ircom & 0xff, down ? "pressed" : "released", keycode);
/* check device address (if selected) */
if (ir_config & 0x4000)
if (addr != ((ir_config >> 16) & 0xff))
return;
if (!keycode) {
printk ("%s: unknown key 0x%02x!!\n",
__FUNCTION__, ircom & 0xff);
__FUNCTION__, data);
return;
}
if (ir_config & 0x0001)
new_toggle = 0; /* RCMM */
else
new_toggle = (ircom & 0x800); /* RC5 */
if (timer_pending (&keyup_timer)) {
del_timer (&keyup_timer);
if (keyup_timer.data != keycode)
if (keyup_timer.data != keycode || new_toggle != old_toggle) {
input_event (&input_dev, EV_KEY, keyup_timer.data, !!0);
}
clear_bit (keycode, input_dev.key);
input_event (&input_dev, EV_KEY, keycode, !0);
} else
input_event (&input_dev, EV_KEY, keycode, 2);
} else
input_event (&input_dev, EV_KEY, keycode, !0);
keyup_timer.expires = jiffies + UP_TIMEOUT;
keyup_timer.data = keycode;
add_timer (&keyup_timer);
old_toggle = new_toggle;
}
static
......@@ -108,17 +133,36 @@ void input_register_keys (void)
}
static void input_repeat_key(unsigned long data)
{
/* dummy routine to disable autorepeat in the input driver */
}
static
int av7110_ir_write_proc (struct file *file, const char *buffer,
unsigned long count, void *data)
{
u32 ir_config;
char *page;
int size = 4 + 256 * sizeof(u16);
if (count < 4 + 256 * sizeof(u16))
if (count < size)
return -EINVAL;
memcpy (&ir_config, buffer, 4);
memcpy (&key_map, buffer + 4, 256 * sizeof(u16));
page = (char *)vmalloc(size);
if( NULL == page ) {
return -ENOMEM;
}
if (copy_from_user(page, buffer, size)) {
vfree(page);
return -EFAULT;
}
memcpy (&ir_config, page, 4);
memcpy (&key_map, page + 4, 256 * sizeof(u16));
vfree(page);
av7110_setup_irc_config (NULL, ir_config);
......@@ -141,10 +185,12 @@ int __init av7110_ir_init (void)
* enable keys
*/
set_bit (EV_KEY, input_dev.evbit);
set_bit (EV_REP, input_dev.evbit);
input_register_keys ();
input_register_device(&input_dev);
input_dev.timer.function = input_repeat_key;
av7110_setup_irc_config (NULL, 0x0001);
av7110_register_irc_handler (av7110_emit_key);
......
......@@ -30,13 +30,10 @@
* the project's page is at http://www.linuxtv.org/dvb/
*/
#include "budget.h"
#include <media/saa7146_vv.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME budget_av
#endif
#include "budget.h"
#include "dvb_functions.h"
struct budget_av {
struct budget budget;
......@@ -48,13 +45,6 @@ struct budget_av {
* INITIALIZATION
****************************************************************************/
static inline
void ddelay(int i)
{
current->state=TASK_INTERRUPTIBLE;
schedule_timeout((HZ*i)/100);
}
static
u8 i2c_readreg (struct dvb_i2c_bus *i2c, u8 id, u8 reg)
......@@ -175,7 +165,7 @@ int budget_av_detach (struct saa7146_dev *dev)
saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
ddelay(20);
dvb_delay(200);
saa7146_unregister_device (&budget_av->vd, dev);
......@@ -221,7 +211,7 @@ int budget_av_attach (struct saa7146_dev* dev,
//test_knc_ci(av7110);
saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
ddelay(50);
dvb_delay(500);
if ((err = saa7113_init (budget_av))) {
budget_av_detach(dev);
......@@ -245,9 +235,11 @@ int budget_av_attach (struct saa7146_dev* dev,
/* what is this? since we don't support open()/close()
notifications, we simply put this into the release handler... */
// saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
ddelay(20);
/*
saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout (20);
*/
/* fixme: find some sane values here... */
saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
......@@ -348,7 +340,7 @@ struct pci_device_id pci_tbl [] = {
}
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
static
struct saa7146_extension budget_extension = {
......
......@@ -28,10 +28,6 @@
*/
#include "budget.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME budget
#endif
#include <linux/module.h>
#include <linux/errno.h>
......@@ -39,12 +35,6 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "input_fake.h"
#endif
struct budget_ci {
struct budget budget;
struct input_dev input_dev;
......@@ -388,7 +378,7 @@ struct pci_device_id pci_tbl[] = {
}
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
static
struct saa7146_extension budget_extension = {
......
#include "budget.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME budget
#endif
int budget_debug = 0;
/****************************************************************************
* General helper functions
****************************************************************************/
static inline void ddelay(int i)
{
current->state=TASK_INTERRUPTIBLE;
schedule_timeout((HZ*i)/100);
}
/****************************************************************************
* TT budget / WinTV Nova
****************************************************************************/
......@@ -142,14 +129,11 @@ int budget_stop_feed(struct dvb_demux_feed *feed)
static
int budget_register(struct budget *budget)
{
int ret;
dmx_frontend_t *dvbfront=&budget->hw_frontend;
struct dvb_demux *dvbdemux=&budget->demux;
int ret;
DEB_EE(("budget: %p\n",budget));
memcpy(budget->demux_id, "demux0_0", 9);
budget->demux_id[5] = budget->dvb_adapter->num + '0';
dvbdemux->priv = (void *) budget;
dvbdemux->filternum = 256;
......@@ -158,33 +142,24 @@ int budget_register(struct budget *budget)
dvbdemux->stop_feed = budget_stop_feed;
dvbdemux->write_to_decoder = NULL;
dvbdemux->dmx.vendor = "CIM";
dvbdemux->dmx.model = "sw";
dvbdemux->dmx.id = budget->demux_id;
dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
DMX_MEMORY_BASED_FILTERING);
dvb_dmx_init(&budget->demux);
dvbfront->id = "hw_frontend";
dvbfront->vendor = "VLSI";
dvbfront->model = "DVB Frontend";
dvbfront->source = DMX_FRONTEND_0;
budget->dmxdev.filternum = 256;
budget->dmxdev.demux = &dvbdemux->dmx;
budget->dmxdev.capabilities = 0;
dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter);
ret=dvbdemux->dmx.add_frontend (&dvbdemux->dmx,
&budget->hw_frontend);
budget->hw_frontend.source = DMX_FRONTEND_0;
ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
if (ret < 0)
return ret;
budget->mem_frontend.id = "mem_frontend";
budget->mem_frontend.vendor = "memory";
budget->mem_frontend.model = "sw";
budget->mem_frontend.source = DMX_MEMORY_FE;
ret=dvbdemux->dmx.add_frontend (&dvbdemux->dmx,
&budget->mem_frontend);
......@@ -278,9 +253,9 @@ int ttpci_budget_init (struct budget *budget,
saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); /* frontend power on */
if (budget_register(budget) == 0)
if (budget_register(budget) == 0) {
return 0;
}
err:
if (budget->grabbing)
vfree(budget->grabbing);
......@@ -312,7 +287,6 @@ int ttpci_budget_deinit (struct budget *budget)
saa7146_pgtable_free (dev->pci, &budget->pt);
vfree (budget->grabbing);
kfree (budget);
return 0;
}
......
......@@ -31,9 +31,7 @@
*/
#include "budget.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME budget_patch
#endif
#include "av7110.h"
#define budget_patch budget
......@@ -49,45 +47,6 @@ struct pci_device_id pci_tbl[] = {
}
};
#define COMMAND (DPRAM_BASE + 0x0FC)
#define DPRAM_BASE 0x4000
#define DEBINOSWAP 0x000e0000
typedef enum {
AudioDAC,
CabADAC,
ON22K,
OFF22K,
MainSwitch,
ADSwitch,
SendDiSEqC,
SetRegister
} AUDCOM;
typedef enum {
COMTYPE_NOCOM,
COMTYPE_PIDFILTER,
COMTYPE_MPEGDECODER,
COMTYPE_OSD,
COMTYPE_BMP,
COMTYPE_ENCODER,
COMTYPE_AUDIODAC,
COMTYPE_REQUEST,
COMTYPE_SYSTEM,
COMTYPE_REC_PLAY,
COMTYPE_COMMON_IF,
COMTYPE_PID_FILTER,
COMTYPE_PES,
COMTYPE_TS,
COMTYPE_VIDEO,
COMTYPE_AUDIO,
COMTYPE_CI_LL,
} COMTYPE;
static
int wdebi(struct budget_patch *budget, u32 config, int addr, u32 val, int count)
{
......@@ -235,31 +194,34 @@ int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_d
** (74HCT4040, LVC74) for the generation of this VSYNC signal,
** which seems that can be done perfectly without this :-)).
*/
#define WRITE_RPS1(x) dev->d_rps1.cpu_addr[ cnt++ ] = cpu_to_le32(x)
cnt = 0; // Setup RPS1 "program" (p35)
// Wait reset Source Line Counter Threshold (p36)
dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS);
WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
// Wait Source Line Counter Threshold (p36)
dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | EVT_HS);
WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
// Set GPIO3=1 (p42)
dev->rps1[cnt++]=cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
dev->rps1[cnt++]=cpu_to_le32(GPIO3_MSK);
dev->rps1[cnt++]=cpu_to_le32(SAA7146_GPIO_OUTHI<<24);
WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
// Wait reset Source Line Counter Threshold (p36)
dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS);
WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
// Wait Source Line Counter Threshold
dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | EVT_HS);
WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
// Set GPIO3=0 (p42)
dev->rps1[cnt++]=cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
dev->rps1[cnt++]=cpu_to_le32(GPIO3_MSK);
dev->rps1[cnt++]=cpu_to_le32(SAA7146_GPIO_OUTLO<<24);
WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
// Jump to begin of RPS program (p37)
dev->rps1[cnt++]=cpu_to_le32(CMD_JUMP);
dev->rps1[cnt++]=cpu_to_le32(virt_to_bus(&dev->rps1[0]));
WRITE_RPS1(cpu_to_le32(CMD_JUMP));
WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
// Fix VSYNC level
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
// Set RPS1 Address register to point to RPS code (r108 p42)
saa7146_write(dev, RPS_ADDR1, virt_to_bus(&dev->rps1[0]));
saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
// Set Source Line Counter Threshold, using BRS (rCC p43)
saa7146_write(dev, RPS_THRESH1, ((TS_HEIGHT/2) | MASK_12));
// Enable RPS1 (rFC p33)
......
......@@ -30,18 +30,7 @@
*/
#include "budget.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME budget
#endif
static inline void ddelay(int i)
{
current->state=TASK_INTERRUPTIBLE;
schedule_timeout((HZ*i)/100);
}
#include "dvb_functions.h"
static
void Set22K (struct budget *budget, int state)
......@@ -87,7 +76,7 @@ void DiseqcSendByte (struct budget *budget, int data)
static
int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, int burst)
int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
{
struct saa7146_dev *dev=budget->dev;
int i;
......@@ -110,7 +99,7 @@ int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, int burst)
udelay(12500);
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
}
ddelay(2);
dvb_delay(20);
}
return 0;
......@@ -146,7 +135,7 @@ int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
}
case FE_DISEQC_SEND_BURST:
SendDiSEqCMsg (budget, 0, NULL, (int) arg);
SendDiSEqCMsg (budget, 0, NULL, (unsigned long)arg);
break;
default:
......@@ -160,15 +149,18 @@ int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
static
int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
{
struct budget *budget;
struct budget *budget = NULL;
int err;
if (!(budget = kmalloc (sizeof(struct budget), GFP_KERNEL)))
budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
if( NULL == budget ) {
return -ENOMEM;
}
DEB_EE(("budget: %p\n",budget));
DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget));
if ((err = ttpci_budget_init (budget, dev, info))) {
printk("==> failed\n");
kfree (budget);
return err;
}
......@@ -194,6 +186,7 @@ int budget_detach (struct saa7146_dev* dev)
err = ttpci_budget_deinit (budget);
kfree (budget);
dev->ext_priv = NULL;
return err;
}
......@@ -222,7 +215,7 @@ struct pci_device_id pci_tbl[] = {
}
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
static
struct saa7146_extension budget_extension = {
......
#ifndef __BUDGET_DVB__
#define __BUDGET_DVB__
#include <media/saa7146.h>
#include "dvb_i2c.h"
#include "dvb_frontend.h"
#include "dvbdev.h"
......@@ -10,8 +12,6 @@
#include "dvb_filter.h"
#include "dvb_net.h"
#include <media/saa7146.h>
extern int budget_debug;
struct budget_info {
......@@ -24,7 +24,7 @@ struct budget {
/* devices */
struct dvb_device dvb_dev;
dvb_net_t dvb_net;
struct dvb_net dvb_net;
struct saa7146_dev *dev;
......@@ -37,12 +37,11 @@ struct budget {
struct tasklet_struct fidb_tasklet;
struct tasklet_struct vpe_tasklet;
dmxdev_t dmxdev;
struct dmxdev dmxdev;
struct dvb_demux demux;
char demux_id[16];
dmx_frontend_t hw_frontend;
dmx_frontend_t mem_frontend;
struct dmx_frontend hw_frontend;
struct dmx_frontend mem_frontend;
int fe_synced;
struct semaphore pid_mutex;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment