summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/mantis
diff options
context:
space:
mode:
authorManu Abraham <abraham.manu@gmail.com>2009-12-04 05:56:35 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-01-17 11:55:43 -0200
commit3e978a8284080d801d20cda377d9cf7c12fe68b9 (patch)
tree797536140340fc3c1b4e4968d0fdd44ddbbb2088 /drivers/media/dvb/mantis
parentad0ac434cb3b34640a4e81d7e80a1512c6e40253 (diff)
downloadlinux-3e978a8284080d801d20cda377d9cf7c12fe68b9.tar.gz
linux-3e978a8284080d801d20cda377d9cf7c12fe68b9.tar.bz2
linux-3e978a8284080d801d20cda377d9cf7c12fe68b9.zip
V4L/DVB (13797): [Mantis/Hopper/TDA665x] Large overhaul,
* Initial go at VP-3028, VP-3030 devices. * I2C communication improvements, * Add TDA665x support Signed-off-by: Manu Abraham <manu@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/mantis')
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c11
-rw-r--r--drivers/media/dvb/mantis/mantis_dma.c3
-rw-r--r--drivers/media/dvb/mantis/mantis_dvb.c22
-rw-r--r--drivers/media/dvb/mantis/mantis_i2c.c141
-rw-r--r--drivers/media/dvb/mantis/mantis_i2c.h3
-rw-r--r--drivers/media/dvb/mantis/mantis_ioc.c42
-rw-r--r--drivers/media/dvb/mantis/mantis_vp3030.c52
8 files changed, 158 insertions, 117 deletions
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 749e3f3dd06b..01a9ff07d770 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -219,7 +219,6 @@ static void __devexit hopper_pci_remove(struct pci_dev *pdev)
struct mantis_pci *mantis = pci_get_drvdata(pdev);
if (mantis) {
-// mantis_uart_exit(mantis);
mantis_dvb_exit(mantis);
mantis_dma_exit(mantis);
mantis_i2c_exit(mantis);
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index d486c7fcb453..638177ce72a2 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -50,7 +50,6 @@ static char *label[10] = {
"RACK"
};
-
static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
{
u32 stat = 0, mask = 0, lstat = 0, mstat = 0;
@@ -199,6 +198,14 @@ static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_dev
return err;
+fail7:
+ dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err);
+ mantis_uart_exit(mantis);
+
+fail6:
+ dprintk(MANTIS_ERROR, 1, "ERROR: Mantis CA exit! <%d>", err);
+ mantis_ca_exit(mantis);
+
fail5:
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB exit! <%d>", err);
mantis_dvb_exit(mantis);
@@ -228,8 +235,6 @@ static void __devexit mantis_pci_remove(struct pci_dev *pdev)
struct mantis_pci *mantis = pci_get_drvdata(pdev);
if (mantis) {
- mantis_uart_exit(mantis);
-// mantis_ca_exit(mantis);
mantis_dvb_exit(mantis);
mantis_dma_exit(mantis);
mantis_i2c_exit(mantis);
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
index 8ebcd96b2b7d..eab3645f7acb 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -153,8 +153,7 @@ int mantis_dma_init(struct mantis_pci *mantis)
if (mantis_alloc_buffers(mantis) < 0) {
dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer");
- // Stop RISC Engine
-// mmwrite(mmread(MANTIS_DMA_CTL) & ~MANTIS_RISC_EN, MANTIS_DMA_CTL);
+ /* Stop RISC Engine */
mmwrite(0, MANTIS_DMA_CTL);
goto err;
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c
index be911d76daa7..42f658b06a66 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -252,14 +252,19 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)
err5:
tasklet_kill(&mantis->tasklet);
dvb_net_release(&mantis->dvbnet);
+
err4:
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+
err3:
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+
err2:
dvb_dmxdev_release(&mantis->dmxdev);
+
err1:
dvb_dmx_release(&mantis->demux);
+
err0:
dvb_unregister_adapter(&mantis->dvb_adapter);
@@ -271,21 +276,24 @@ int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
{
int err;
- err = mantis_frontend_shutdown(mantis);
- if (err != 0)
- dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
+ if (mantis->fe) {
+// mantis_ca_exit(mantis);
+ err = mantis_frontend_shutdown(mantis);
+ if (err != 0)
+ dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
+
+ dvb_unregister_frontend(mantis->fe);
+ }
-// mantis_ca_exit(mantis);
tasklet_kill(&mantis->tasklet);
dvb_net_release(&mantis->dvbnet);
+
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+
dvb_dmxdev_release(&mantis->dmxdev);
dvb_dmx_release(&mantis->demux);
- if (mantis->fe)
- dvb_unregister_frontend(mantis->fe);
-
dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
dvb_unregister_adapter(&mantis->dvb_adapter);
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c
index ba55f0a9a10f..16b9e7e77b82 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.c
+++ b/drivers/media/dvb/mantis/mantis_i2c.c
@@ -35,38 +35,9 @@
#define I2C_HW_B_MANTIS 0x1c
-static int mantis_ack_wait(struct mantis_pci *mantis)
-{
- int rc = 0;
- u32 timeout = 0;
-
- if (wait_event_timeout(mantis->i2c_wq,
- mantis->mantis_int_stat & MANTIS_INT_I2CDONE,
- msecs_to_jiffies(50)) == -ERESTARTSYS) {
-
- dprintk(MANTIS_DEBUG, 1, "Master !I2CDONE");
- rc = -EREMOTEIO;
- }
-
- while (!(mantis->mantis_int_stat & MANTIS_INT_I2CRACK)) {
- dprintk(MANTIS_DEBUG, 1, "Waiting for Slave RACK");
- mantis->mantis_int_stat = mmread(MANTIS_INT_STAT);
- msleep(5);
- timeout++;
- if (timeout > 500) {
- dprintk(MANTIS_ERROR, 1, "Slave RACK Fail !");
- rc = -EREMOTEIO;
- break;
- }
- }
- udelay(350);
-
- return rc;
-}
-
static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
{
- u32 rxd, i;
+ u32 rxd, i, stat, trials;
dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ",
__func__, msg->addr);
@@ -82,10 +53,15 @@ static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
mmwrite(rxd, MANTIS_I2CDATA_CTL);
- if (mantis_ack_wait(mantis) != 0) {
- dprintk(MANTIS_DEBUG, 1, "ACK failed<R>");
- return -EREMOTEIO;
+
+ /* wait for xfer completion */
+ for (trials = 0; trials < 100; trials++) {
+ udelay(500);
+ stat = mmread(MANTIS_INT_STAT);
+ if (stat & MANTIS_INT_I2CDONE)
+ break;
}
+
rxd = mmread(MANTIS_I2CDATA_CTL);
msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
@@ -98,7 +74,7 @@ static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
{
int i;
- u32 txd = 0;
+ u32 txd = 0, stat, trials;
dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ",
__func__, msg->addr);
@@ -115,9 +91,13 @@ static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg
mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
mmwrite(txd, MANTIS_I2CDATA_CTL);
- if (mantis_ack_wait(mantis) != 0) {
- dprintk(MANTIS_DEBUG, 1, "ACK failed<W>");
- return -EREMOTEIO;
+
+ /* wait for xfer completion */
+ for (trials = 0; trials < 100; trials++) {
+ udelay(500);
+ stat = mmread(MANTIS_INT_STAT);
+ if (stat & MANTIS_INT_I2CDONE)
+ break;
}
}
dprintk(MANTIS_INFO, 0, "]\n");
@@ -127,20 +107,77 @@ static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg
static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
{
- int ret = 0, i;
+ int ret = 0, i = 0, trials;
+ u32 stat, data, txd;
struct mantis_pci *mantis;
+ struct mantis_hwconfig *config;
mantis = i2c_get_adapdata(adapter);
+ BUG_ON(!mantis);
+ config = mantis->hwconfig;
+ BUG_ON(!config);
+
+ dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
mutex_lock(&mantis->i2c_lock);
- for (i = 0; i < num; i++) {
- if (msgs[i].flags & I2C_M_RD)
- ret = mantis_i2c_read(mantis, &msgs[i]);
- else
- ret = mantis_i2c_write(mantis, &msgs[i]);
-
- if (ret < 0)
- goto bail_out;
+
+ while (i < num) {
+ /* Byte MODE */
+ if (((i + 1) < num) &&
+ (msgs[i].len < 2) &&
+ (msgs[i + 1].len < 2) &&
+ (msgs[i + 1].flags & I2C_M_RD)) {
+
+ dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n");
+
+ /* Read operation */
+ txd = msgs[i].addr << 25 | (0x1 << 24)
+ | (msgs[i].buf[0] << 16)
+ | MANTIS_I2C_RATE_3;
+
+ mmwrite(txd, MANTIS_I2CDATA_CTL);
+ /* wait for xfer completion */
+ for (trials = 0; trials < 100; trials++) {
+ udelay(500);
+ stat = mmread(MANTIS_INT_STAT);
+ if (stat & MANTIS_INT_I2CDONE)
+ break;
+ }
+
+ /* check for xfer completion */
+ if (stat & MANTIS_INT_I2CDONE) {
+ /* check xfer was acknowledged */
+ if (stat & MANTIS_INT_I2CRACK) {
+ data = mmread(MANTIS_I2CDATA_CTL);
+ msgs[i + 1].buf[0] = (data >> 8) & 0xff;
+ dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
+ } else {
+ /* I/O error */
+ dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
+ ret = -EIO;
+ break;
+ }
+ } else {
+ /* I/O error */
+ dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
+ ret = -EIO;
+ break;
+ }
+ i += 2; /* Write/Read operation in one go */
+ }
+
+ if (i < num) {
+ if (msgs[i].flags & I2C_M_RD)
+ ret = mantis_i2c_read(mantis, &msgs[i]);
+ else
+ ret = mantis_i2c_write(mantis, &msgs[i]);
+
+ i++;
+ if (ret < 0)
+ goto bail_out;
+ }
+
}
+
mutex_unlock(&mantis->i2c_lock);
return num;
@@ -189,9 +226,9 @@ int __devinit mantis_i2c_init(struct mantis_pci *mantis)
intstat = mmread(MANTIS_INT_STAT);
intmask = mmread(MANTIS_INT_MASK);
mmwrite(intstat, MANTIS_INT_STAT);
- mmwrite(intmask | MANTIS_INT_I2CDONE, MANTIS_INT_MASK);
-
- dprintk(MANTIS_DEBUG, 1, "Status=<%02x> Mask=<%02x>", intstat, intmask);
+ dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
+ intmask = mmread(MANTIS_INT_MASK);
+ mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
return 0;
}
@@ -199,6 +236,12 @@ EXPORT_SYMBOL_GPL(mantis_i2c_init);
int __devexit mantis_i2c_exit(struct mantis_pci *mantis)
{
+ u32 intmask;
+
+ dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
+ intmask = mmread(MANTIS_INT_MASK);
+ mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
+
dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
return i2c_del_adapter(&mantis->adapter);
}
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/dvb/mantis/mantis_i2c.h
index 1e49ecfeee3e..d40da4fa0007 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.h
+++ b/drivers/media/dvb/mantis/mantis_i2c.h
@@ -1,6 +1,9 @@
#ifndef __MANTIS_I2C_H
#define __MANTIS_I2C_H
+#define I2C_STOP (1 << 0)
+#define I2C_READ (1 << 1)
+
extern int mantis_i2c_init(struct mantis_pci *mantis);
extern int mantis_i2c_exit(struct mantis_pci *mantis);
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c
index 4700088f0388..448e2c3e3445 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/dvb/mantis/mantis_ioc.c
@@ -36,13 +36,14 @@
#include "mantis_reg.h"
#include "mantis_ioc.h"
-static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
+static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
{
struct i2c_adapter *adapter = &mantis->adapter;
-
int err;
+ u8 buf = reg;
+
struct i2c_msg msg[] = {
- { .addr = 0x50, .flags = 0, .buf = data, .len = 1 },
+ { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
{ .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
};
@@ -56,32 +57,12 @@ static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
return 0;
}
-
-static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
-{
- struct i2c_adapter *adapter = &mantis->adapter;
- int err;
-
- struct i2c_msg msg = { .addr = 0x50, .flags = 0, .buf = data, .len = length };
-
- err = i2c_transfer(adapter, &msg, 1);
- if (err < 0) {
- dprintk(MANTIS_ERROR, 1, "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",
- err, length, data[0], data[1]);
-
- return err;
- }
-
- return 0;
-}
-
int mantis_get_mac(struct mantis_pci *mantis)
{
int err;
+ u8 mac_addr[6] = {0};
- mantis->mac_address[0] = 0x08;
-
- err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
+ err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
if (err < 0) {
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
@@ -90,9 +71,12 @@ int mantis_get_mac(struct mantis_pci *mantis)
dprintk(MANTIS_ERROR, 0,
" MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
- mantis->mac_address[0], mantis->mac_address[1],
- mantis->mac_address[2], mantis->mac_address[3],
- mantis->mac_address[4], mantis->mac_address[5]);
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5]);
return 0;
}
@@ -103,12 +87,14 @@ void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
{
u32 cur;
+ dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
cur = mmread(MANTIS_GPIF_ADDR);
if (value)
mantis->gpio_status = cur | (1 << bitpos);
else
mantis->gpio_status = cur & (~(1 << bitpos));
+ dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
mmwrite(0x00, MANTIS_GPIF_DOUT);
}
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c
index 4b974eeefa9e..9efcfa7b8ab4 100644
--- a/drivers/media/dvb/mantis/mantis_vp3030.c
+++ b/drivers/media/dvb/mantis/mantis_vp3030.c
@@ -30,46 +30,41 @@
#include "dvb_net.h"
#include "zl10353.h"
+#include "tda665x.h"
#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
#include "mantis_vp3030.h"
struct zl10353_config mantis_vp3030_config = {
- .demod_address = 0x0f,
+ .demod_address = 0x0f,
+};
+
+struct tda665x_config env57h12d5_config = {
+ .name = "ENV57H12D5 (ET-50DT)",
+ .addr = 0x60,
+ .frequency_min = 47000000,
+ .frequency_max = 862000000,
+ .frequency_offst = 3616667,
+ .ref_multiplier = 6, /* 1/6 MHz */
+ .ref_divider = 100000, /* 1/6 MHz */
};
#define MANTIS_MODEL_NAME "VP-3030"
#define MANTIS_DEV_TYPE "DVB-T"
-int panasonic_en57h12d5_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- u8 buf[4];
- int rc;
- struct mantis_pci *mantis = fe->dvb->priv;
-
- struct i2c_msg tuner_msg = {
- .addr = 0x60,
- .flags = 0,
- .buf = buf,
- .len = sizeof (buf)
- };
-
- if ((params->frequency < 950000) || (params->frequency > 2150000))
- return -EINVAL;
- rc = i2c_transfer(&mantis->adapter, &tuner_msg, 1);
- if (rc != 1) {
- printk("%s: I2C Transfer returned [%d]\n", __func__, rc);
- return -EIO;
- }
- msleep_interruptible(1);
- printk("%s: Send params to tuner ok!!!\n", __func__);
-
- return 0;
-}
static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
{
struct i2c_adapter *adapter = &mantis->adapter;
+ struct mantis_hwconfig *config = mantis->hwconfig;
+ int err = 0;
+
+ gpio_set_bits(mantis, config->reset, 0);
+ msleep(100);
+ err = mantis_frontend_power(mantis, POWER_ON);
+ msleep(100);
+ gpio_set_bits(mantis, config->reset, 1);
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
fe = zl10353_attach(&mantis_vp3030_config, adapter);
@@ -77,6 +72,7 @@ static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
if (!fe)
return -1;
+ tda665x_attach(fe, &env57h12d5_config, adapter);
mantis->fe = fe;
dprintk(MANTIS_ERROR, 1, "Done!");
@@ -93,4 +89,6 @@ struct mantis_hwconfig vp3030_config = {
.bytes = 0,
.frontend_init = vp3030_frontend_init,
+ .power = GPIF_A12,
+ .reset = GPIF_A13,
};