aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorManu Abraham <abraham.manu@gmail.com>2009-12-04 03:56:35 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-01-17 08:55:43 -0500
commit3e978a8284080d801d20cda377d9cf7c12fe68b9 (patch)
tree797536140340fc3c1b4e4968d0fdd44ddbbb2088 /drivers/media
parentad0ac434cb3b34640a4e81d7e80a1512c6e40253 (diff)
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')
-rw-r--r--drivers/media/dvb/frontends/Kconfig11
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/tda665x.c257
-rw-r--r--drivers/media/dvb/frontends/tda665x.h52
-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
12 files changed, 479 insertions, 117 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a3b8b697349..7820ca084b1 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -587,6 +587,17 @@ config DVB_ATBM8830
587 help 587 help
588 A DMB-TH tuner module. Say Y when you want to support this frontend. 588 A DMB-TH tuner module. Say Y when you want to support this frontend.
589 589
590config DVB_TDA665x
591 tristate "TDA665x tuner"
592 depends on DVB_CORE && I2C
593 default m if DVB_FE_CUSTOMISE
594 help
595 Support for tuner modules based on Philips TDA6650/TDA6651 chips.
596 Say Y when you want to support this chip.
597
598 Currently supported tuners:
599 * Panasonic ENV57H12D5 (ET-50DT)
600
590comment "Tools to develop new frontends" 601comment "Tools to develop new frontends"
591 602
592config DVB_DUMMY_FE 603config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 47575cc7b69..59f7b880355 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_DVB_TDA10048) += tda10048.o
64obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o 64obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
65obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 65obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
66obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o 66obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
67obj-$(CONFIG_DVB_TDA665x) += tda665x.o
67obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o 68obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
68obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o 69obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
69obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o 70obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c
new file mode 100644
index 00000000000..0732a2d38e1
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda665x.c
@@ -0,0 +1,257 @@
1/*
2 TDA665x tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23
24#include "dvb_frontend.h"
25#include "tda665x.h"
26
27struct tda665x_state {
28 struct dvb_frontend *fe;
29 struct i2c_adapter *i2c;
30 const struct tda665x_config *config;
31
32 u32 frequency;
33 u32 bandwidth;
34};
35
36static int tda665x_read(struct tda665x_state *state, u8 *buf)
37{
38 const struct tda665x_config *config = state->config;
39 int err = 0;
40 struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };
41
42 err = i2c_transfer(state->i2c, &msg, 1);
43 if (err != 1)
44 goto exit;
45
46 return err;
47exit:
48 printk("%s: I/O Error err=<%d>\n", __func__, err);
49 return err;
50}
51
52static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
53{
54 const struct tda665x_config *config = state->config;
55 int err = 0;
56 struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };
57
58 err = i2c_transfer(state->i2c, &msg, 1);
59 if (err != 1)
60 goto exit;
61
62 return err;
63exit:
64 printk("%s: I/O Error err=<%d>\n", __func__, err);
65 return err;
66}
67
68static int tda665x_get_state(struct dvb_frontend *fe,
69 enum tuner_param param,
70 struct tuner_state *tstate)
71{
72 struct tda665x_state *state = fe->tuner_priv;
73 int err = 0;
74
75 switch (param) {
76 case DVBFE_TUNER_FREQUENCY:
77 tstate->frequency = state->frequency;
78 break;
79 case DVBFE_TUNER_BANDWIDTH:
80 break;
81 default:
82 printk("%s: Unknown parameter (param=%d)\n", __func__, param);
83 err = -EINVAL;
84 break;
85 }
86
87 return err;
88}
89
90static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
91{
92 struct tda665x_state *state = fe->tuner_priv;
93 u8 result = 0;
94 int err = 0;
95
96 *status = 0;
97
98 err = tda665x_read(state, &result);
99 if (err < 0)
100 goto exit;
101
102 if ((result >> 6) & 0x01) {
103 printk("%s: Tuner Phase Locked\n", __func__);
104 *status = 1;
105 }
106
107 return err;
108exit:
109 printk("%s: I/O Error\n", __func__);
110 return err;
111}
112
113static int tda665x_set_state(struct dvb_frontend *fe,
114 enum tuner_param param,
115 struct tuner_state *tstate)
116{
117 struct tda665x_state *state = fe->tuner_priv;
118 const struct tda665x_config *config = state->config;
119 u32 frequency, status = 0;
120 u8 buf[4];
121 int err = 0;
122
123 if (param & DVBFE_TUNER_FREQUENCY) {
124
125 frequency = tstate->frequency;
126 if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
127 printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
128 return -EINVAL;
129 }
130
131 frequency += config->frequency_offst;
132 frequency *= config->ref_multiplier;
133 frequency += config->ref_divider >> 1;
134 frequency /= config->ref_divider;
135
136 buf[0] = (u8 ) (frequency & 0x7f00) >> 8;
137 buf[1] = (u8 ) (frequency & 0x00ff) >> 0;
138 buf[2] = 0x80 | 0x40 | 0x02;
139 buf[3] = 0x00;
140
141 /* restore frequency */
142 frequency = tstate->frequency;
143
144 if (frequency < 153000000) {
145 /* VHF-L */
146 buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
147 if (frequency < 68000000)
148 buf[3] |= 0x40; /* 83uA */
149 if (frequency < 1040000000)
150 buf[3] |= 0x60; /* 122uA */
151 if (frequency < 1250000000)
152 buf[3] |= 0x80; /* 163uA */
153 else
154 buf[3] |= 0xa0; /* 254uA */
155 } else if (frequency < 438000000) {
156 /* VHF-H */
157 buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
158 if (frequency < 230000000)
159 buf[3] |= 0x40;
160 if (frequency < 300000000)
161 buf[3] |= 0x60;
162 else
163 buf[3] |= 0x80;
164 } else {
165 /* UHF */
166 buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
167 if (frequency < 470000000)
168 buf[3] |= 0x60;
169 if (frequency < 526000000)
170 buf[3] |= 0x80;
171 else
172 buf[3] |= 0xa0;
173 }
174
175 /* Set params */
176 err = tda665x_write(state, buf, 5);
177 if (err < 0)
178 goto exit;
179
180 /* sleep for some time */
181 printk("%s: Waiting to Phase LOCK\n", __func__);
182 msleep(20);
183 /* check status */
184 err = tda665x_get_status(fe, &status);
185 if (err < 0)
186 goto exit;
187
188 if (status == 1) {
189 printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
190 state->frequency = frequency; /* cache successful state */
191 } else {
192 printk("%s: No Phase lock: status=%d\n", __func__, status);
193 }
194 } else {
195 printk("%s: Unknown parameter (param=%d)\n", __func__, param);
196 return -EINVAL;
197 }
198
199 return 0;
200exit:
201 printk("%s: I/O Error\n", __func__);
202 return err;
203}
204
205static int tda665x_release(struct dvb_frontend *fe)
206{
207 struct tda665x_state *state = fe->tuner_priv;
208
209 fe->tuner_priv = NULL;
210 kfree(state);
211 return 0;
212}
213
214static struct dvb_tuner_ops tda665x_ops = {
215
216 .set_state = tda665x_set_state,
217 .get_state = tda665x_get_state,
218 .get_status = tda665x_get_status,
219 .release = tda665x_release
220};
221
222struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
223 const struct tda665x_config *config,
224 struct i2c_adapter *i2c)
225{
226 struct tda665x_state *state = NULL;
227 struct dvb_tuner_info *info;
228
229 state = kzalloc(sizeof (struct tda665x_state), GFP_KERNEL);
230 if (state == NULL)
231 goto exit;
232
233 state->config = config;
234 state->i2c = i2c;
235 state->fe = fe;
236 fe->tuner_priv = state;
237 fe->ops.tuner_ops = tda665x_ops;
238 info = &fe->ops.tuner_ops.info;
239
240 memcpy(info->name, config->name, sizeof (config->name));
241 info->frequency_min = config->frequency_min;
242 info->frequency_max = config->frequency_max;
243 info->frequency_step = config->frequency_offst;
244
245 printk("%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
246
247 return fe;
248
249exit:
250 kfree(state);
251 return NULL;
252}
253EXPORT_SYMBOL(tda665x_attach);
254
255MODULE_DESCRIPTION("TDA665x driver");
256MODULE_AUTHOR("Manu Abraham");
257MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda665x.h b/drivers/media/dvb/frontends/tda665x.h
new file mode 100644
index 00000000000..c0b544d8ef5
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda665x.h
@@ -0,0 +1,52 @@
1/*
2 TDA665x tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#ifndef __TDA665x_H
21#define __TDA665x_H
22
23struct tda665x_config {
24 char name[128];
25
26 u8 addr;
27 u32 frequency_min;
28 u32 frequency_max;
29 u32 frequency_offst;
30 u32 ref_multiplier;
31 u32 ref_divider;
32};
33
34#if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE))
35
36extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
37 const struct tda665x_config *config,
38 struct i2c_adapter *i2c);
39
40#else
41
42static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
43 const struct tda665x_config *config,
44 struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49
50#endif /* CONFIG_DVB_TDA665x */
51
52#endif /* __TDA665x_H */
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 749e3f3dd06..01a9ff07d77 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)
219 struct mantis_pci *mantis = pci_get_drvdata(pdev); 219 struct mantis_pci *mantis = pci_get_drvdata(pdev);
220 220
221 if (mantis) { 221 if (mantis) {
222// mantis_uart_exit(mantis);
223 mantis_dvb_exit(mantis); 222 mantis_dvb_exit(mantis);
224 mantis_dma_exit(mantis); 223 mantis_dma_exit(mantis);
225 mantis_i2c_exit(mantis); 224 mantis_i2c_exit(mantis);
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index d486c7fcb45..638177ce72a 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] = {
50 "RACK" 50 "RACK"
51}; 51};
52 52
53
54static irqreturn_t mantis_irq_handler(int irq, void *dev_id) 53static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
55{ 54{
56 u32 stat = 0, mask = 0, lstat = 0, mstat = 0; 55 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
199 198
200 return err; 199 return err;
201 200
201fail7:
202 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err);
203 mantis_uart_exit(mantis);
204
205fail6:
206 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis CA exit! <%d>", err);
207 mantis_ca_exit(mantis);
208
202fail5: 209fail5:
203 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB exit! <%d>", err); 210 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB exit! <%d>", err);
204 mantis_dvb_exit(mantis); 211 mantis_dvb_exit(mantis);
@@ -228,8 +235,6 @@ static void __devexit mantis_pci_remove(struct pci_dev *pdev)
228 struct mantis_pci *mantis = pci_get_drvdata(pdev); 235 struct mantis_pci *mantis = pci_get_drvdata(pdev);
229 236
230 if (mantis) { 237 if (mantis) {
231 mantis_uart_exit(mantis);
232// mantis_ca_exit(mantis);
233 mantis_dvb_exit(mantis); 238 mantis_dvb_exit(mantis);
234 mantis_dma_exit(mantis); 239 mantis_dma_exit(mantis);
235 mantis_i2c_exit(mantis); 240 mantis_i2c_exit(mantis);
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
index 8ebcd96b2b7..eab3645f7ac 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)
153 if (mantis_alloc_buffers(mantis) < 0) { 153 if (mantis_alloc_buffers(mantis) < 0) {
154 dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); 154 dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer");
155 155
156 // Stop RISC Engine 156 /* Stop RISC Engine */
157// mmwrite(mmread(MANTIS_DMA_CTL) & ~MANTIS_RISC_EN, MANTIS_DMA_CTL);
158 mmwrite(0, MANTIS_DMA_CTL); 157 mmwrite(0, MANTIS_DMA_CTL);
159 158
160 goto err; 159 goto err;
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c
index be911d76daa..42f658b06a6 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)
252err5: 252err5:
253 tasklet_kill(&mantis->tasklet); 253 tasklet_kill(&mantis->tasklet);
254 dvb_net_release(&mantis->dvbnet); 254 dvb_net_release(&mantis->dvbnet);
255
255err4: 256err4:
256 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); 257 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
258
257err3: 259err3:
258 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); 260 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
261
259err2: 262err2:
260 dvb_dmxdev_release(&mantis->dmxdev); 263 dvb_dmxdev_release(&mantis->dmxdev);
264
261err1: 265err1:
262 dvb_dmx_release(&mantis->demux); 266 dvb_dmx_release(&mantis->demux);
267
263err0: 268err0:
264 dvb_unregister_adapter(&mantis->dvb_adapter); 269 dvb_unregister_adapter(&mantis->dvb_adapter);
265 270
@@ -271,21 +276,24 @@ int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
271{ 276{
272 int err; 277 int err;
273 278
274 err = mantis_frontend_shutdown(mantis); 279 if (mantis->fe) {
275 if (err != 0) 280// mantis_ca_exit(mantis);
276 dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); 281 err = mantis_frontend_shutdown(mantis);
282 if (err != 0)
283 dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
284
285 dvb_unregister_frontend(mantis->fe);
286 }
277 287
278// mantis_ca_exit(mantis);
279 tasklet_kill(&mantis->tasklet); 288 tasklet_kill(&mantis->tasklet);
280 dvb_net_release(&mantis->dvbnet); 289 dvb_net_release(&mantis->dvbnet);
290
281 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); 291 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
282 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); 292 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
293
283 dvb_dmxdev_release(&mantis->dmxdev); 294 dvb_dmxdev_release(&mantis->dmxdev);
284 dvb_dmx_release(&mantis->demux); 295 dvb_dmx_release(&mantis->demux);
285 296
286 if (mantis->fe)
287 dvb_unregister_frontend(mantis->fe);
288
289 dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); 297 dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
290 dvb_unregister_adapter(&mantis->dvb_adapter); 298 dvb_unregister_adapter(&mantis->dvb_adapter);
291 299
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c
index ba55f0a9a10..16b9e7e77b8 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.c
+++ b/drivers/media/dvb/mantis/mantis_i2c.c
@@ -35,38 +35,9 @@
35 35
36#define I2C_HW_B_MANTIS 0x1c 36#define I2C_HW_B_MANTIS 0x1c
37 37
38static int mantis_ack_wait(struct mantis_pci *mantis)
39{
40 int rc = 0;
41 u32 timeout = 0;
42
43 if (wait_event_timeout(mantis->i2c_wq,
44 mantis->mantis_int_stat & MANTIS_INT_I2CDONE,
45 msecs_to_jiffies(50)) == -ERESTARTSYS) {
46
47 dprintk(MANTIS_DEBUG, 1, "Master !I2CDONE");
48 rc = -EREMOTEIO;
49 }
50
51 while (!(mantis->mantis_int_stat & MANTIS_INT_I2CRACK)) {
52 dprintk(MANTIS_DEBUG, 1, "Waiting for Slave RACK");
53 mantis->mantis_int_stat = mmread(MANTIS_INT_STAT);
54 msleep(5);
55 timeout++;
56 if (timeout > 500) {
57 dprintk(MANTIS_ERROR, 1, "Slave RACK Fail !");
58 rc = -EREMOTEIO;
59 break;
60 }
61 }
62 udelay(350);
63
64 return rc;
65}
66
67static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg) 38static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
68{ 39{
69 u32 rxd, i; 40 u32 rxd, i, stat, trials;
70 41
71 dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ", 42 dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ",
72 __func__, msg->addr); 43 __func__, msg->addr);
@@ -82,10 +53,15 @@ static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
82 53
83 mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); 54 mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
84 mmwrite(rxd, MANTIS_I2CDATA_CTL); 55 mmwrite(rxd, MANTIS_I2CDATA_CTL);
85 if (mantis_ack_wait(mantis) != 0) { 56
86 dprintk(MANTIS_DEBUG, 1, "ACK failed<R>"); 57 /* wait for xfer completion */
87 return -EREMOTEIO; 58 for (trials = 0; trials < 100; trials++) {
59 udelay(500);
60 stat = mmread(MANTIS_INT_STAT);
61 if (stat & MANTIS_INT_I2CDONE)
62 break;
88 } 63 }
64
89 rxd = mmread(MANTIS_I2CDATA_CTL); 65 rxd = mmread(MANTIS_I2CDATA_CTL);
90 msg->buf[i] = (u8)((rxd >> 8) & 0xFF); 66 msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
91 dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); 67 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)
98static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg) 74static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
99{ 75{
100 int i; 76 int i;
101 u32 txd = 0; 77 u32 txd = 0, stat, trials;
102 78
103 dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ", 79 dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ",
104 __func__, msg->addr); 80 __func__, msg->addr);
@@ -115,9 +91,13 @@ static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg
115 91
116 mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); 92 mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
117 mmwrite(txd, MANTIS_I2CDATA_CTL); 93 mmwrite(txd, MANTIS_I2CDATA_CTL);
118 if (mantis_ack_wait(mantis) != 0) { 94
119 dprintk(MANTIS_DEBUG, 1, "ACK failed<W>"); 95 /* wait for xfer completion */
120 return -EREMOTEIO; 96 for (trials = 0; trials < 100; trials++) {
97 udelay(500);
98 stat = mmread(MANTIS_INT_STAT);
99 if (stat & MANTIS_INT_I2CDONE)
100 break;
121 } 101 }
122 } 102 }
123 dprintk(MANTIS_INFO, 0, "]\n"); 103 dprintk(MANTIS_INFO, 0, "]\n");
@@ -127,20 +107,77 @@ static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg
127 107
128static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) 108static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
129{ 109{
130 int ret = 0, i; 110 int ret = 0, i = 0, trials;
111 u32 stat, data, txd;
131 struct mantis_pci *mantis; 112 struct mantis_pci *mantis;
113 struct mantis_hwconfig *config;
132 114
133 mantis = i2c_get_adapdata(adapter); 115 mantis = i2c_get_adapdata(adapter);
116 BUG_ON(!mantis);
117 config = mantis->hwconfig;
118 BUG_ON(!config);
119
120 dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
134 mutex_lock(&mantis->i2c_lock); 121 mutex_lock(&mantis->i2c_lock);
135 for (i = 0; i < num; i++) { 122
136 if (msgs[i].flags & I2C_M_RD) 123 while (i < num) {
137 ret = mantis_i2c_read(mantis, &msgs[i]); 124 /* Byte MODE */
138 else 125 if (((i + 1) < num) &&
139 ret = mantis_i2c_write(mantis, &msgs[i]); 126 (msgs[i].len < 2) &&
140 127 (msgs[i + 1].len < 2) &&
141 if (ret < 0) 128 (msgs[i + 1].flags & I2C_M_RD)) {
142 goto bail_out; 129
130 dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n");
131
132 /* Read operation */
133 txd = msgs[i].addr << 25 | (0x1 << 24)
134 | (msgs[i].buf[0] << 16)
135 | MANTIS_I2C_RATE_3;
136
137 mmwrite(txd, MANTIS_I2CDATA_CTL);
138 /* wait for xfer completion */
139 for (trials = 0; trials < 100; trials++) {
140 udelay(500);
141 stat = mmread(MANTIS_INT_STAT);
142 if (stat & MANTIS_INT_I2CDONE)
143 break;
144 }
145
146 /* check for xfer completion */
147 if (stat & MANTIS_INT_I2CDONE) {
148 /* check xfer was acknowledged */
149 if (stat & MANTIS_INT_I2CRACK) {
150 data = mmread(MANTIS_I2CDATA_CTL);
151 msgs[i + 1].buf[0] = (data >> 8) & 0xff;
152 dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
153 } else {
154 /* I/O error */
155 dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
156 ret = -EIO;
157 break;
158 }
159 } else {
160 /* I/O error */
161 dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
162 ret = -EIO;
163 break;
164 }
165 i += 2; /* Write/Read operation in one go */
166 }
167
168 if (i < num) {
169 if (msgs[i].flags & I2C_M_RD)
170 ret = mantis_i2c_read(mantis, &msgs[i]);
171 else
172 ret = mantis_i2c_write(mantis, &msgs[i]);
173
174 i++;
175 if (ret < 0)
176 goto bail_out;
177 }
178
143 } 179 }
180
144 mutex_unlock(&mantis->i2c_lock); 181 mutex_unlock(&mantis->i2c_lock);
145 182
146 return num; 183 return num;
@@ -189,9 +226,9 @@ int __devinit mantis_i2c_init(struct mantis_pci *mantis)
189 intstat = mmread(MANTIS_INT_STAT); 226 intstat = mmread(MANTIS_INT_STAT);
190 intmask = mmread(MANTIS_INT_MASK); 227 intmask = mmread(MANTIS_INT_MASK);
191 mmwrite(intstat, MANTIS_INT_STAT); 228 mmwrite(intstat, MANTIS_INT_STAT);
192 mmwrite(intmask | MANTIS_INT_I2CDONE, MANTIS_INT_MASK); 229 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
193 230 intmask = mmread(MANTIS_INT_MASK);
194 dprintk(MANTIS_DEBUG, 1, "Status=<%02x> Mask=<%02x>", intstat, intmask); 231 mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
195 232
196 return 0; 233 return 0;
197} 234}
@@ -199,6 +236,12 @@ EXPORT_SYMBOL_GPL(mantis_i2c_init);
199 236
200int __devexit mantis_i2c_exit(struct mantis_pci *mantis) 237int __devexit mantis_i2c_exit(struct mantis_pci *mantis)
201{ 238{
239 u32 intmask;
240
241 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
242 intmask = mmread(MANTIS_INT_MASK);
243 mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
244
202 dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); 245 dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
203 return i2c_del_adapter(&mantis->adapter); 246 return i2c_del_adapter(&mantis->adapter);
204} 247}
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/dvb/mantis/mantis_i2c.h
index 1e49ecfeee3..d40da4fa000 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.h
+++ b/drivers/media/dvb/mantis/mantis_i2c.h
@@ -1,6 +1,9 @@
1#ifndef __MANTIS_I2C_H 1#ifndef __MANTIS_I2C_H
2#define __MANTIS_I2C_H 2#define __MANTIS_I2C_H
3 3
4#define I2C_STOP (1 << 0)
5#define I2C_READ (1 << 1)
6
4extern int mantis_i2c_init(struct mantis_pci *mantis); 7extern int mantis_i2c_init(struct mantis_pci *mantis);
5extern int mantis_i2c_exit(struct mantis_pci *mantis); 8extern int mantis_i2c_exit(struct mantis_pci *mantis);
6 9
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c
index 4700088f038..448e2c3e344 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/dvb/mantis/mantis_ioc.c
@@ -36,13 +36,14 @@
36#include "mantis_reg.h" 36#include "mantis_reg.h"
37#include "mantis_ioc.h" 37#include "mantis_ioc.h"
38 38
39static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) 39static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
40{ 40{
41 struct i2c_adapter *adapter = &mantis->adapter; 41 struct i2c_adapter *adapter = &mantis->adapter;
42
43 int err; 42 int err;
43 u8 buf = reg;
44
44 struct i2c_msg msg[] = { 45 struct i2c_msg msg[] = {
45 { .addr = 0x50, .flags = 0, .buf = data, .len = 1 }, 46 { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
46 { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length }, 47 { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
47 }; 48 };
48 49
@@ -56,32 +57,12 @@ static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
56 57
57 return 0; 58 return 0;
58} 59}
59
60static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
61{
62 struct i2c_adapter *adapter = &mantis->adapter;
63 int err;
64
65 struct i2c_msg msg = { .addr = 0x50, .flags = 0, .buf = data, .len = length };
66
67 err = i2c_transfer(adapter, &msg, 1);
68 if (err < 0) {
69 dprintk(MANTIS_ERROR, 1, "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",
70 err, length, data[0], data[1]);
71
72 return err;
73 }
74
75 return 0;
76}
77
78int mantis_get_mac(struct mantis_pci *mantis) 60int mantis_get_mac(struct mantis_pci *mantis)
79{ 61{
80 int err; 62 int err;
63 u8 mac_addr[6] = {0};
81 64
82 mantis->mac_address[0] = 0x08; 65 err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
83
84 err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
85 if (err < 0) { 66 if (err < 0) {
86 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err); 67 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
87 68
@@ -90,9 +71,12 @@ int mantis_get_mac(struct mantis_pci *mantis)
90 71
91 dprintk(MANTIS_ERROR, 0, 72 dprintk(MANTIS_ERROR, 0,
92 " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", 73 " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
93 mantis->mac_address[0], mantis->mac_address[1], 74 mac_addr[0],
94 mantis->mac_address[2], mantis->mac_address[3], 75 mac_addr[1],
95 mantis->mac_address[4], mantis->mac_address[5]); 76 mac_addr[2],
77 mac_addr[3],
78 mac_addr[4],
79 mac_addr[5]);
96 80
97 return 0; 81 return 0;
98} 82}
@@ -103,12 +87,14 @@ void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
103{ 87{
104 u32 cur; 88 u32 cur;
105 89
90 dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
106 cur = mmread(MANTIS_GPIF_ADDR); 91 cur = mmread(MANTIS_GPIF_ADDR);
107 if (value) 92 if (value)
108 mantis->gpio_status = cur | (1 << bitpos); 93 mantis->gpio_status = cur | (1 << bitpos);
109 else 94 else
110 mantis->gpio_status = cur & (~(1 << bitpos)); 95 mantis->gpio_status = cur & (~(1 << bitpos));
111 96
97 dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
112 mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); 98 mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
113 mmwrite(0x00, MANTIS_GPIF_DOUT); 99 mmwrite(0x00, MANTIS_GPIF_DOUT);
114} 100}
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c
index 4b974eeefa9..9efcfa7b8ab 100644
--- a/drivers/media/dvb/mantis/mantis_vp3030.c
+++ b/drivers/media/dvb/mantis/mantis_vp3030.c
@@ -30,46 +30,41 @@
30#include "dvb_net.h" 30#include "dvb_net.h"
31 31
32#include "zl10353.h" 32#include "zl10353.h"
33#include "tda665x.h"
33#include "mantis_common.h" 34#include "mantis_common.h"
35#include "mantis_ioc.h"
36#include "mantis_dvb.h"
34#include "mantis_vp3030.h" 37#include "mantis_vp3030.h"
35 38
36struct zl10353_config mantis_vp3030_config = { 39struct zl10353_config mantis_vp3030_config = {
37 .demod_address = 0x0f, 40 .demod_address = 0x0f,
41};
42
43struct tda665x_config env57h12d5_config = {
44 .name = "ENV57H12D5 (ET-50DT)",
45 .addr = 0x60,
46 .frequency_min = 47000000,
47 .frequency_max = 862000000,
48 .frequency_offst = 3616667,
49 .ref_multiplier = 6, /* 1/6 MHz */
50 .ref_divider = 100000, /* 1/6 MHz */
38}; 51};
39 52
40#define MANTIS_MODEL_NAME "VP-3030" 53#define MANTIS_MODEL_NAME "VP-3030"
41#define MANTIS_DEV_TYPE "DVB-T" 54#define MANTIS_DEV_TYPE "DVB-T"
42 55
43int panasonic_en57h12d5_set_params(struct dvb_frontend *fe,
44 struct dvb_frontend_parameters *params)
45{
46 u8 buf[4];
47 int rc;
48 struct mantis_pci *mantis = fe->dvb->priv;
49
50 struct i2c_msg tuner_msg = {
51 .addr = 0x60,
52 .flags = 0,
53 .buf = buf,
54 .len = sizeof (buf)
55 };
56
57 if ((params->frequency < 950000) || (params->frequency > 2150000))
58 return -EINVAL;
59 rc = i2c_transfer(&mantis->adapter, &tuner_msg, 1);
60 if (rc != 1) {
61 printk("%s: I2C Transfer returned [%d]\n", __func__, rc);
62 return -EIO;
63 }
64 msleep_interruptible(1);
65 printk("%s: Send params to tuner ok!!!\n", __func__);
66
67 return 0;
68}
69 56
70static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 57static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
71{ 58{
72 struct i2c_adapter *adapter = &mantis->adapter; 59 struct i2c_adapter *adapter = &mantis->adapter;
60 struct mantis_hwconfig *config = mantis->hwconfig;
61 int err = 0;
62
63 gpio_set_bits(mantis, config->reset, 0);
64 msleep(100);
65 err = mantis_frontend_power(mantis, POWER_ON);
66 msleep(100);
67 gpio_set_bits(mantis, config->reset, 1);
73 68
74 dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); 69 dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
75 fe = zl10353_attach(&mantis_vp3030_config, adapter); 70 fe = zl10353_attach(&mantis_vp3030_config, adapter);
@@ -77,6 +72,7 @@ static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
77 if (!fe) 72 if (!fe)
78 return -1; 73 return -1;
79 74
75 tda665x_attach(fe, &env57h12d5_config, adapter);
80 mantis->fe = fe; 76 mantis->fe = fe;
81 dprintk(MANTIS_ERROR, 1, "Done!"); 77 dprintk(MANTIS_ERROR, 1, "Done!");
82 78
@@ -93,4 +89,6 @@ struct mantis_hwconfig vp3030_config = {
93 .bytes = 0, 89 .bytes = 0,
94 90
95 .frontend_init = vp3030_frontend_init, 91 .frontend_init = vp3030_frontend_init,
92 .power = GPIF_A12,
93 .reset = GPIF_A13,
96}; 94};