133 строки
3.5 KiB
C
133 строки
3.5 KiB
C
/*
|
|
zr36120_i2c.c - Zoran 36120/36125 based framegrabbers
|
|
|
|
Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/delay.h>
|
|
#include <asm/io.h>
|
|
|
|
#include <linux/video_decoder.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
#include "tuner.h"
|
|
#include "zr36120.h"
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
/* I2C functions */
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
/* software I2C functions */
|
|
|
|
#define I2C_DELAY 10
|
|
|
|
static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data)
|
|
{
|
|
struct zoran *ztv = (struct zoran*)bus->data;
|
|
unsigned int b = 0;
|
|
if (data) b |= ztv->card->swapi2c ? ZORAN_I2C_SCL : ZORAN_I2C_SDA;
|
|
if (ctrl) b |= ztv->card->swapi2c ? ZORAN_I2C_SDA : ZORAN_I2C_SCL;
|
|
zrwrite(b, ZORAN_I2C);
|
|
udelay(I2C_DELAY);
|
|
}
|
|
|
|
static int i2c_getdataline(struct i2c_bus *bus)
|
|
{
|
|
struct zoran *ztv = (struct zoran*)bus->data;
|
|
if (ztv->card->swapi2c)
|
|
return zrread(ZORAN_I2C) & ZORAN_I2C_SCL;
|
|
return zrread(ZORAN_I2C) & ZORAN_I2C_SDA;
|
|
}
|
|
|
|
static
|
|
void attach_inform(struct i2c_bus *bus, int id)
|
|
{
|
|
struct zoran *ztv = (struct zoran*)bus->data;
|
|
struct video_decoder_capability dc;
|
|
int rv;
|
|
|
|
switch (id) {
|
|
case I2C_DRIVERID_VIDEODECODER:
|
|
DEBUG(printk(CARD_INFO "decoder attached\n",CARD));
|
|
|
|
/* fetch the capabilities of the decoder */
|
|
rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc);
|
|
if (rv) {
|
|
DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD));
|
|
break;
|
|
}
|
|
DEBUG(printk(CARD_DEBUG "capabilities %d %d %d\n",CARD,dc.flags,dc.inputs,dc.outputs));
|
|
|
|
/* Test if the decoder can de VBI transfers */
|
|
if (dc.flags & 16 /*VIDEO_DECODER_VBI*/)
|
|
ztv->have_decoder = 2;
|
|
else
|
|
ztv->have_decoder = 1;
|
|
break;
|
|
case I2C_DRIVERID_TUNER:
|
|
ztv->have_tuner = 1;
|
|
DEBUG(printk(CARD_INFO "tuner attached\n",CARD));
|
|
if (ztv->tuner_type >= 0)
|
|
{
|
|
if (i2c_control_device(&ztv->i2c,I2C_DRIVERID_TUNER,TUNER_SET_TYPE,&ztv->tuner_type)<0)
|
|
DEBUG(printk(CARD_INFO "attach_inform; tuner won't be set to type %d\n",CARD,ztv->tuner_type));
|
|
}
|
|
break;
|
|
default:
|
|
DEBUG(printk(CARD_INFO "attach_inform; unknown device id=%d\n",CARD,id));
|
|
break;
|
|
}
|
|
}
|
|
|
|
static
|
|
void detach_inform(struct i2c_bus *bus, int id)
|
|
{
|
|
struct zoran *ztv = (struct zoran*)bus->data;
|
|
|
|
switch (id) {
|
|
case I2C_DRIVERID_VIDEODECODER:
|
|
ztv->have_decoder = 0;
|
|
DEBUG(printk(CARD_INFO "decoder detached\n",CARD));
|
|
break;
|
|
case I2C_DRIVERID_TUNER:
|
|
ztv->have_tuner = 0;
|
|
DEBUG(printk(CARD_INFO "tuner detached\n",CARD));
|
|
break;
|
|
default:
|
|
DEBUG(printk(CARD_INFO "detach_inform; unknown device id=%d\n",CARD,id));
|
|
break;
|
|
}
|
|
}
|
|
|
|
struct i2c_bus zoran_i2c_bus_template =
|
|
{
|
|
"ZR36120",
|
|
I2C_BUSID_ZORAN,
|
|
NULL,
|
|
|
|
SPIN_LOCK_UNLOCKED,
|
|
|
|
attach_inform,
|
|
detach_inform,
|
|
|
|
i2c_setlines,
|
|
i2c_getdataline,
|
|
NULL,
|
|
NULL
|
|
};
|