Commit | Line | Data |
---|---|---|
b2eb1312 MA |
1 | /* |
2 | Mantis VP-2040 driver | |
3 | ||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | */ | |
20 | ||
b3b96144 MA |
21 | #include <linux/signal.h> |
22 | #include <linux/sched.h> | |
23 | #include <linux/interrupt.h> | |
24 | ||
25 | #include "dmxdev.h" | |
26 | #include "dvbdev.h" | |
27 | #include "dvb_demux.h" | |
28 | #include "dvb_frontend.h" | |
29 | #include "dvb_net.h" | |
30 | ||
31 | #include "tda1002x.h" | |
b2eb1312 | 32 | #include "mantis_common.h" |
bc832fa2 MA |
33 | #include "mantis_ioc.h" |
34 | #include "mantis_dvb.h" | |
b2eb1312 MA |
35 | #include "mantis_vp2040.h" |
36 | ||
37 | #define MANTIS_MODEL_NAME "VP-2040" | |
38 | #define MANTIS_DEV_TYPE "DVB-C" | |
39 | ||
b3b96144 MA |
40 | struct tda1002x_config vp2040_tda1002x_cu1216_config = { |
41 | .demod_address = 0x18 >> 1, | |
42 | .invert = 1, | |
43 | }; | |
44 | ||
45 | struct tda10023_config vp2040_tda10023_cu1216_config = { | |
46 | .demod_address = 0x18 >> 1, | |
47 | .invert = 1, | |
48 | }; | |
49 | ||
50 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | |
51 | { | |
52 | struct mantis_pci *mantis = fe->dvb->priv; | |
53 | struct i2c_adapter *adapter = &mantis->adapter; | |
54 | ||
55 | u8 buf[6]; | |
f5ae4f6f | 56 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; |
b3b96144 MA |
57 | int i; |
58 | ||
59 | #define CU1216_IF 36125000 | |
60 | #define TUNER_MUL 62500 | |
61 | ||
62 | u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | |
63 | ||
64 | buf[0] = (div >> 8) & 0x7f; | |
65 | buf[1] = div & 0xff; | |
66 | buf[2] = 0xce; | |
67 | buf[3] = (params->frequency < 150000000 ? 0x01 : | |
68 | params->frequency < 445000000 ? 0x02 : 0x04); | |
69 | buf[4] = 0xde; | |
70 | buf[5] = 0x20; | |
71 | ||
72 | if (fe->ops.i2c_gate_ctrl) | |
73 | fe->ops.i2c_gate_ctrl(fe, 1); | |
74 | ||
75 | if (i2c_transfer(adapter, &msg, 1) != 1) | |
76 | return -EIO; | |
77 | ||
78 | /* wait for the pll lock */ | |
79 | msg.flags = I2C_M_RD; | |
80 | msg.len = 1; | |
81 | for (i = 0; i < 20; i++) { | |
82 | if (fe->ops.i2c_gate_ctrl) | |
83 | fe->ops.i2c_gate_ctrl(fe, 1); | |
84 | ||
85 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | |
86 | break; | |
87 | ||
88 | msleep(10); | |
89 | } | |
90 | ||
91 | /* switch the charge pump to the lower current */ | |
92 | msg.flags = 0; | |
93 | msg.len = 2; | |
94 | msg.buf = &buf[2]; | |
95 | buf[2] &= ~0x40; | |
96 | if (fe->ops.i2c_gate_ctrl) | |
97 | fe->ops.i2c_gate_ctrl(fe, 1); | |
98 | ||
99 | if (i2c_transfer(adapter, &msg, 1) != 1) | |
100 | return -EIO; | |
101 | ||
102 | return 0; | |
103 | } | |
104 | ||
105 | static u8 read_pwm(struct mantis_pci *mantis) | |
106 | { | |
107 | struct i2c_adapter *adapter = &mantis->adapter; | |
108 | ||
109 | u8 b = 0xff; | |
110 | u8 pwm; | |
111 | struct i2c_msg msg[] = { | |
112 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | |
113 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | |
114 | }; | |
115 | ||
116 | if ((i2c_transfer(adapter, msg, 2) != 2) | |
117 | || (pwm == 0xff)) | |
118 | pwm = 0x48; | |
119 | ||
120 | return pwm; | |
121 | } | |
122 | ||
123 | static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | |
124 | { | |
125 | struct i2c_adapter *adapter = &mantis->adapter; | |
126 | ||
bc832fa2 | 127 | int err = 0; |
b3b96144 | 128 | |
bc832fa2 MA |
129 | err = mantis_frontend_power(mantis, POWER_ON); |
130 | if (err == 0) { | |
131 | mantis_frontend_soft_reset(mantis); | |
132 | msleep(250); | |
133 | ||
134 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | |
135 | fe = tda10021_attach(&vp2040_tda1002x_cu1216_config, | |
b3b96144 MA |
136 | adapter, |
137 | read_pwm(mantis)); | |
138 | ||
139 | if (fe) { | |
140 | dprintk(MANTIS_ERROR, 1, | |
bc832fa2 | 141 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", |
b3b96144 | 142 | vp2040_tda1002x_cu1216_config.demod_address); |
bc832fa2 MA |
143 | } else { |
144 | fe = tda10023_attach(&vp2040_tda10023_cu1216_config, | |
145 | adapter, | |
146 | read_pwm(mantis)); | |
147 | ||
148 | if (fe) { | |
149 | dprintk(MANTIS_ERROR, 1, | |
150 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | |
151 | vp2040_tda1002x_cu1216_config.demod_address); | |
152 | } | |
b3b96144 | 153 | } |
b3b96144 | 154 | |
bc832fa2 MA |
155 | if (fe) { |
156 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | |
157 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | |
158 | } else { | |
159 | return -1; | |
160 | } | |
b3b96144 | 161 | } else { |
bc832fa2 MA |
162 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", |
163 | adapter->name, | |
164 | err); | |
b3b96144 | 165 | |
bc832fa2 MA |
166 | return -EIO; |
167 | } | |
b3b96144 MA |
168 | mantis->fe = fe; |
169 | dprintk(MANTIS_DEBUG, 1, "Done!"); | |
170 | ||
171 | return 0; | |
172 | } | |
173 | ||
174 | struct mantis_hwconfig vp2040_config = { | |
b2eb1312 MA |
175 | .model_name = MANTIS_MODEL_NAME, |
176 | .dev_type = MANTIS_DEV_TYPE, | |
177 | .ts_size = MANTIS_TS_204, | |
b3b96144 | 178 | |
add20636 MA |
179 | .baud_rate = MANTIS_BAUD_9600, |
180 | .parity = MANTIS_PARITY_NONE, | |
181 | .bytes = 0, | |
b2eb1312 | 182 | |
b3b96144 | 183 | .frontend_init = vp2040_frontend_init, |
bc832fa2 MA |
184 | .power = GPIF_A12, |
185 | .reset = GPIF_A13, | |
b2eb1312 | 186 | }; |