aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-07-21 14:46:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-04 19:21:34 -0500
commit99ac54125490f16f7434f82fcb73bbb88290b38e (patch)
tree75d28f81fbe285f8a3d6fd8ee72d6a159a615ab6 /drivers/media/common
parent6fb167000e6b726bc9f129af08b6aad3ef075da4 (diff)
[media] mt2063: Fix analog/digital set params logic
The driver were using a hacky way of setting analog and digital frequencies. Remove the hack and properly add the tuner logic for each supported type of standard. I was tempted to add more standards there, like SECAM and to fix radio (as stepping seems broken), but I opted to keep it as-is, as tests would be needed to add additional standards. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/tuners/mt2063.c390
-rw-r--r--drivers/media/common/tuners/mt2063.h1
2 files changed, 190 insertions, 201 deletions
diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c
index 5154b9d08384..4f634ad24e14 100644
--- a/drivers/media/common/tuners/mt2063.c
+++ b/drivers/media/common/tuners/mt2063.c
@@ -2,6 +2,7 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/module.h> 3#include <linux/module.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/videodev2.h>
5 6
6#include "mt2063.h" 7#include "mt2063.h"
7 8
@@ -201,21 +202,6 @@ enum MT2063_Register_Offsets {
201 MT2063_REG_END_REGS 202 MT2063_REG_END_REGS
202}; 203};
203 204
204enum MTTune_atv_standard {
205 MTTUNEA_UNKNOWN = 0,
206 MTTUNEA_PAL_B,
207 MTTUNEA_PAL_G,
208 MTTUNEA_PAL_I,
209 MTTUNEA_PAL_L,
210 MTTUNEA_PAL_MN,
211 MTTUNEA_PAL_DK,
212 MTTUNEA_DIGITAL,
213 MTTUNEA_FMRADIO,
214 MTTUNEA_DVBC,
215 MTTUNEA_DVBT
216};
217
218
219struct mt2063_state { 205struct mt2063_state {
220 struct i2c_adapter *i2c; 206 struct i2c_adapter *i2c;
221 207
@@ -224,7 +210,6 @@ struct mt2063_state {
224 struct dvb_frontend *frontend; 210 struct dvb_frontend *frontend;
225 struct tuner_state status; 211 struct tuner_state status;
226 212
227 enum MTTune_atv_standard tv_type;
228 u32 frequency; 213 u32 frequency;
229 u32 srate; 214 u32 srate;
230 u32 bandwidth; 215 u32 bandwidth;
@@ -258,9 +243,11 @@ static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
258 msg.buf[0] = reg; 243 msg.buf[0] = reg;
259 memcpy(msg.buf + 1, data, len); 244 memcpy(msg.buf + 1, data, len);
260 245
261 fe->ops.i2c_gate_ctrl(fe, 1); 246 if (fe->ops.i2c_gate_ctrl)
247 fe->ops.i2c_gate_ctrl(fe, 1);
262 ret = i2c_transfer(state->i2c, &msg, 1); 248 ret = i2c_transfer(state->i2c, &msg, 1);
263 fe->ops.i2c_gate_ctrl(fe, 0); 249 if (fe->ops.i2c_gate_ctrl)
250 fe->ops.i2c_gate_ctrl(fe, 0);
264 251
265 if (ret < 0) 252 if (ret < 0)
266 printk(KERN_ERR "%s error ret=%d\n", __func__, ret); 253 printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
@@ -297,7 +284,8 @@ static u32 mt2063_read(struct mt2063_state *state,
297 struct dvb_frontend *fe = state->frontend; 284 struct dvb_frontend *fe = state->frontend;
298 u32 i = 0; 285 u32 i = 0;
299 286
300 fe->ops.i2c_gate_ctrl(fe, 1); 287 if (fe->ops.i2c_gate_ctrl)
288 fe->ops.i2c_gate_ctrl(fe, 1);
301 289
302 for (i = 0; i < cnt; i++) { 290 for (i = 0; i < cnt; i++) {
303 int ret; 291 int ret;
@@ -320,7 +308,9 @@ static u32 mt2063_read(struct mt2063_state *state,
320 if (ret < 0) 308 if (ret < 0)
321 break; 309 break;
322 } 310 }
323 fe->ops.i2c_gate_ctrl(fe, 0); 311 if (fe->ops.i2c_gate_ctrl)
312 fe->ops.i2c_gate_ctrl(fe, 0);
313
324 return status; 314 return status;
325} 315}
326 316
@@ -997,7 +987,7 @@ static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
997 * 987 *
998 * This function returns 0, if no lock, 1 if locked and a value < 1 if error 988 * This function returns 0, if no lock, 1 if locked and a value < 1 if error
999 */ 989 */
1000unsigned int mt2063_lockStatus(struct mt2063_state *state) 990static unsigned int mt2063_lockStatus(struct mt2063_state *state)
1001{ 991{
1002 const u32 nMaxWait = 100; /* wait a maximum of 100 msec */ 992 const u32 nMaxWait = 100; /* wait a maximum of 100 msec */
1003 const u32 nPollRate = 2; /* poll status bits every 2 ms */ 993 const u32 nPollRate = 2; /* poll status bits every 2 ms */
@@ -1030,7 +1020,6 @@ unsigned int mt2063_lockStatus(struct mt2063_state *state)
1030 */ 1020 */
1031 return 0; 1021 return 0;
1032} 1022}
1033EXPORT_SYMBOL_GPL(mt2063_lockStatus);
1034 1023
1035/* 1024/*
1036 * mt2063_set_dnc_output_enable() 1025 * mt2063_set_dnc_output_enable()
@@ -1922,132 +1911,6 @@ static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1922 return status; 1911 return status;
1923} 1912}
1924 1913
1925int mt2063_setTune(struct dvb_frontend *fe, u32 f_in, u32 bw_in,
1926 enum MTTune_atv_standard tv_type)
1927{
1928 struct mt2063_state *state = fe->tuner_priv;
1929 u32 status = 0;
1930 s32 pict_car = 0;
1931 s32 pict2chanb_vsb = 0;
1932 s32 pict2chanb_snd = 0;
1933 s32 pict2snd1 = 0;
1934 s32 pict2snd2 = 0;
1935 s32 ch_bw = 0;
1936 s32 if_mid = 0;
1937 s32 rcvr_mode = 0;
1938
1939 switch (tv_type) {
1940 case MTTUNEA_PAL_B:{
1941 pict_car = 38900000;
1942 ch_bw = 8000000;
1943 pict2chanb_vsb = -1250000;
1944 pict2snd1 = 5500000;
1945 pict2snd2 = 5742000;
1946 rcvr_mode = 1;
1947 break;
1948 }
1949 case MTTUNEA_PAL_G:{
1950 pict_car = 38900000;
1951 ch_bw = 7000000;
1952 pict2chanb_vsb = -1250000;
1953 pict2snd1 = 5500000;
1954 pict2snd2 = 0;
1955 rcvr_mode = 1;
1956 break;
1957 }
1958 case MTTUNEA_PAL_I:{
1959 pict_car = 38900000;
1960 ch_bw = 8000000;
1961 pict2chanb_vsb = -1250000;
1962 pict2snd1 = 6000000;
1963 pict2snd2 = 0;
1964 rcvr_mode = 1;
1965 break;
1966 }
1967 case MTTUNEA_PAL_L:{
1968 pict_car = 38900000;
1969 ch_bw = 8000000;
1970 pict2chanb_vsb = -1250000;
1971 pict2snd1 = 6500000;
1972 pict2snd2 = 0;
1973 rcvr_mode = 1;
1974 break;
1975 }
1976 case MTTUNEA_PAL_MN:{
1977 pict_car = 38900000;
1978 ch_bw = 6000000;
1979 pict2chanb_vsb = -1250000;
1980 pict2snd1 = 4500000;
1981 pict2snd2 = 0;
1982 rcvr_mode = 1;
1983 break;
1984 }
1985 case MTTUNEA_PAL_DK:{
1986 pict_car = 38900000;
1987 ch_bw = 8000000;
1988 pict2chanb_vsb = -1250000;
1989 pict2snd1 = 6500000;
1990 pict2snd2 = 0;
1991 rcvr_mode = 1;
1992 break;
1993 }
1994 case MTTUNEA_DIGITAL:{
1995 pict_car = 36125000;
1996 ch_bw = 8000000;
1997 pict2chanb_vsb = -(ch_bw / 2);
1998 pict2snd1 = 0;
1999 pict2snd2 = 0;
2000 rcvr_mode = 2;
2001 break;
2002 }
2003 case MTTUNEA_FMRADIO:{
2004 pict_car = 38900000;
2005 ch_bw = 8000000;
2006 pict2chanb_vsb = -(ch_bw / 2);
2007 pict2snd1 = 0;
2008 pict2snd2 = 0;
2009 rcvr_mode = 4;
2010 break;
2011 }
2012 case MTTUNEA_DVBC:{
2013 pict_car = 36125000;
2014 ch_bw = 8000000;
2015 pict2chanb_vsb = -(ch_bw / 2);
2016 pict2snd1 = 0;
2017 pict2snd2 = 0;
2018 rcvr_mode = MT2063_CABLE_QAM;
2019 break;
2020 }
2021 case MTTUNEA_DVBT:{
2022 pict_car = 36125000;
2023 ch_bw = bw_in;
2024 pict2chanb_vsb = -(ch_bw / 2);
2025 pict2snd1 = 0;
2026 pict2snd2 = 0;
2027 rcvr_mode = MT2063_OFFAIR_COFDM;
2028 break;
2029 }
2030 case MTTUNEA_UNKNOWN:
2031 break;
2032 default:
2033 break;
2034 }
2035
2036 pict2chanb_snd = pict2chanb_vsb - ch_bw;
2037 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2038
2039 state->AS_Data.f_LO2_Step = 125000;
2040 state->AS_Data.f_out = if_mid;
2041 state->AS_Data.f_out_bw = ch_bw + 750000;
2042 status = MT2063_SetReceiverMode(state, rcvr_mode);
2043 if (status < 0)
2044 return status;
2045
2046 status = MT2063_Tune(state, (f_in + (pict2chanb_vsb + (ch_bw / 2))));
2047
2048 return status;
2049}
2050
2051static const u8 MT2063B0_defaults[] = { 1914static const u8 MT2063B0_defaults[] = {
2052 /* Reg, Value */ 1915 /* Reg, Value */
2053 0x19, 0x05, 1916 0x19, 0x05,
@@ -2300,83 +2163,208 @@ static int mt2063_init(struct dvb_frontend *fe)
2300 return 0; 2163 return 0;
2301} 2164}
2302 2165
2303static int mt2063_get_status(struct dvb_frontend *fe, u32 * status) 2166static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
2304{ 2167{
2305 int rc = 0; 2168 struct mt2063_state *state = fe->tuner_priv;
2169 int status;
2306 2170
2307 /* FIXME: add get tuner lock status */ 2171 *tuner_status = 0;
2172 status = mt2063_lockStatus(state);
2173 if (status < 0)
2174 return status;
2175 if (status)
2176 *tuner_status = TUNER_STATUS_LOCKED;
2308 2177
2309 return rc; 2178 return 0;
2310} 2179}
2311 2180
2312static int mt2063_get_state(struct dvb_frontend *fe, 2181static int mt2063_release(struct dvb_frontend *fe)
2313 enum tuner_param param, struct tuner_state *tunstate)
2314{ 2182{
2315 struct mt2063_state *state = fe->tuner_priv; 2183 struct mt2063_state *state = fe->tuner_priv;
2316 2184
2317 switch (param) { 2185 fe->tuner_priv = NULL;
2318 case DVBFE_TUNER_FREQUENCY: 2186 kfree(state);
2319 /* get frequency */ 2187
2320 break; 2188 return 0;
2321 case DVBFE_TUNER_TUNERSTEP: 2189}
2322 break; 2190
2323 case DVBFE_TUNER_IFFREQ: 2191static int mt2063_set_analog_params(struct dvb_frontend *fe,
2324 break; 2192 struct analog_parameters *params)
2325 case DVBFE_TUNER_BANDWIDTH: 2193{
2326 /* get bandwidth */ 2194 struct mt2063_state *state = fe->tuner_priv;
2327 break; 2195 s32 pict_car = 0;
2328 case DVBFE_TUNER_REFCLOCK: 2196 s32 pict2chanb_vsb = 0;
2329 tunstate->refclock = mt2063_lockStatus(state); 2197 s32 pict2chanb_snd = 0;
2198 s32 pict2snd1 = 0;
2199 s32 pict2snd2 = 0;
2200 s32 ch_bw = 0;
2201 s32 if_mid = 0;
2202 s32 rcvr_mode = 0;
2203 int status;
2204
2205 switch (params->mode) {
2206 case V4L2_TUNER_RADIO:
2207 pict_car = 38900000;
2208 ch_bw = 8000000;
2209 pict2chanb_vsb = -(ch_bw / 2);
2210 pict2snd1 = 0;
2211 pict2snd2 = 0;
2212 rcvr_mode = MT2063_OFFAIR_ANALOG;
2330 break; 2213 break;
2331 default: 2214 case V4L2_TUNER_ANALOG_TV:
2215 rcvr_mode = MT2063_CABLE_ANALOG;
2216 if (params->std & ~V4L2_STD_MN) {
2217 pict_car = 38900000;
2218 ch_bw = 6000000;
2219 pict2chanb_vsb = -1250000;
2220 pict2snd1 = 4500000;
2221 pict2snd2 = 0;
2222 } else if (params->std & V4L2_STD_PAL_I) {
2223 pict_car = 38900000;
2224 ch_bw = 8000000;
2225 pict2chanb_vsb = -1250000;
2226 pict2snd1 = 6000000;
2227 pict2snd2 = 0;
2228 } else if (params->std & V4L2_STD_PAL_B) {
2229 pict_car = 38900000;
2230 ch_bw = 8000000;
2231 pict2chanb_vsb = -1250000;
2232 pict2snd1 = 5500000;
2233 pict2snd2 = 5742000;
2234 } else if (params->std & V4L2_STD_PAL_G) {
2235 pict_car = 38900000;
2236 ch_bw = 7000000;
2237 pict2chanb_vsb = -1250000;
2238 pict2snd1 = 5500000;
2239 pict2snd2 = 0;
2240 } else if (params->std & V4L2_STD_PAL_DK) {
2241 pict_car = 38900000;
2242 ch_bw = 8000000;
2243 pict2chanb_vsb = -1250000;
2244 pict2snd1 = 6500000;
2245 pict2snd2 = 0;
2246 } else { /* PAL-L */
2247 pict_car = 38900000;
2248 ch_bw = 8000000;
2249 pict2chanb_vsb = -1250000;
2250 pict2snd1 = 6500000;
2251 pict2snd2 = 0;
2252 }
2332 break; 2253 break;
2333 } 2254 }
2255 pict2chanb_snd = pict2chanb_vsb - ch_bw;
2256 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2257
2258 state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
2259 state->AS_Data.f_out = if_mid;
2260 state->AS_Data.f_out_bw = ch_bw + 750000;
2261 status = MT2063_SetReceiverMode(state, rcvr_mode);
2262 if (status < 0)
2263 return status;
2264
2265 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2266 if (status < 0)
2267 return status;
2334 2268
2335 return (int)tunstate->refclock; 2269 state->frequency = params->frequency;
2270 return 0;
2336} 2271}
2337 2272
2338static int mt2063_set_state(struct dvb_frontend *fe, 2273/*
2339 enum tuner_param param, struct tuner_state *tunstate) 2274 * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
2275 * So, the amount of the needed bandwith is given by:
2276 * Bw = Symbol_rate * (1 + 0.15)
2277 * As such, the maximum symbol rate supported by 6 MHz is given by:
2278 * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
2279 */
2280#define MAX_SYMBOL_RATE_6MHz 5217391
2281
2282static int mt2063_set_params(struct dvb_frontend *fe,
2283 struct dvb_frontend_parameters *params)
2340{ 2284{
2341 struct mt2063_state *state = fe->tuner_priv; 2285 struct mt2063_state *state = fe->tuner_priv;
2342 u32 status = 0; 2286 int status;
2343 2287 s32 pict_car = 0;
2344 switch (param) { 2288 s32 pict2chanb_vsb = 0;
2345 case DVBFE_TUNER_FREQUENCY: 2289 s32 pict2chanb_snd = 0;
2346 /* set frequency */ 2290 s32 pict2snd1 = 0;
2347 2291 s32 pict2snd2 = 0;
2348 status = 2292 s32 ch_bw = 0;
2349 mt2063_setTune(fe, 2293 s32 if_mid = 0;
2350 tunstate->frequency, tunstate->bandwidth, 2294 s32 rcvr_mode = 0;
2351 state->tv_type);
2352 2295
2353 state->frequency = tunstate->frequency; 2296 switch (fe->ops.info.type) {
2354 break; 2297 case FE_OFDM:
2355 case DVBFE_TUNER_TUNERSTEP: 2298 switch (params->u.ofdm.bandwidth) {
2356 break; 2299 case BANDWIDTH_6_MHZ:
2357 case DVBFE_TUNER_IFFREQ: 2300 ch_bw = 6000000;
2358 break; 2301 break;
2359 case DVBFE_TUNER_BANDWIDTH: 2302 case BANDWIDTH_7_MHZ:
2360 /* set bandwidth */ 2303 ch_bw = 7000000;
2361 state->bandwidth = tunstate->bandwidth; 2304 break;
2305 case BANDWIDTH_8_MHZ:
2306 ch_bw = 8000000;
2307 break;
2308 default:
2309 return -EINVAL;
2310 }
2311 rcvr_mode = MT2063_OFFAIR_COFDM;
2312 pict_car = 36125000;
2313 pict2chanb_vsb = -(ch_bw / 2);
2314 pict2snd1 = 0;
2315 pict2snd2 = 0;
2362 break; 2316 break;
2363 case DVBFE_TUNER_REFCLOCK: 2317 case FE_QAM:
2364 2318 /*
2319 * Using a 8MHz bandwidth sometimes fail
2320 * with 6MHz-spaced channels, due to inter-carrier
2321 * interference. So, it is better to narrow-down the filter
2322 */
2323 if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz)
2324 ch_bw = 6000000;
2325 else
2326 ch_bw = 8000000;
2327 rcvr_mode = MT2063_CABLE_QAM;
2328 pict_car = 36125000;
2329 pict2snd1 = 0;
2330 pict2snd2 = 0;
2331 pict2chanb_vsb = -(ch_bw / 2);
2365 break; 2332 break;
2366 default: 2333 default:
2367 break; 2334 return -EINVAL;
2368 } 2335 }
2336 pict2chanb_snd = pict2chanb_vsb - ch_bw;
2337 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2338
2339 state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
2340 state->AS_Data.f_out = if_mid;
2341 state->AS_Data.f_out_bw = ch_bw + 750000;
2342 status = MT2063_SetReceiverMode(state, rcvr_mode);
2343 if (status < 0)
2344 return status;
2345
2346 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2347
2348 if (status < 0)
2349 return status;
2369 2350
2370 return (int)status; 2351 state->frequency = params->frequency;
2352 return 0;
2371} 2353}
2372 2354
2373static int mt2063_release(struct dvb_frontend *fe) 2355static int mt2063_get_frequency(struct dvb_frontend *fe, u32 *freq)
2374{ 2356{
2375 struct mt2063_state *state = fe->tuner_priv; 2357 struct mt2063_state *state = fe->tuner_priv;
2376 2358
2377 fe->tuner_priv = NULL; 2359 *freq = state->frequency;
2378 kfree(state); 2360 return 0;
2361}
2362
2363static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2364{
2365 struct mt2063_state *state = fe->tuner_priv;
2379 2366
2367 *bw = state->AS_Data.f_out_bw - 750000;
2380 return 0; 2368 return 0;
2381} 2369}
2382 2370
@@ -2391,9 +2379,11 @@ static struct dvb_tuner_ops mt2063_ops = {
2391 .init = mt2063_init, 2379 .init = mt2063_init,
2392 .sleep = MT2063_Sleep, 2380 .sleep = MT2063_Sleep,
2393 .get_status = mt2063_get_status, 2381 .get_status = mt2063_get_status,
2394 .get_state = mt2063_get_state, 2382 .set_analog_params = mt2063_set_analog_params,
2395 .set_state = mt2063_set_state, 2383 .set_params = mt2063_set_params,
2396 .release = mt2063_release 2384 .get_frequency = mt2063_get_frequency,
2385 .get_bandwidth = mt2063_get_bandwidth,
2386 .release = mt2063_release,
2397}; 2387};
2398 2388
2399struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, 2389struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/mt2063.h b/drivers/media/common/tuners/mt2063.h
index b2e3abf95ec8..62d0e8ec4e99 100644
--- a/drivers/media/common/tuners/mt2063.h
+++ b/drivers/media/common/tuners/mt2063.h
@@ -28,7 +28,6 @@ int mt2063_setTune(struct dvb_frontend *fe, u32 f_in,
28 enum MTTune_atv_standard tv_type); 28 enum MTTune_atv_standard tv_type);
29 29
30/* FIXME: Should use the standard DVB attachment interfaces */ 30/* FIXME: Should use the standard DVB attachment interfaces */
31unsigned int mt2063_lockStatus(struct dvb_frontend *fe);
32unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe); 31unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
33unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe); 32unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
34 33