/* zr36120_i2c.c - Zoran 36120/36125 based framegrabbers Copyright (C) 1998-1999 Pauline Middelink 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 #include #include #include #include #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 };