aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2007-08-27 20:59:08 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:07:41 -0400
commit4adad287de82703fd504fdab7aebe760196bb786 (patch)
treeabdb6772db2f03e6d914c6a5c9b060fbd33fff84 /drivers/media
parent8d0936ed15f509c32e8f81849be3a1cee80e2225 (diff)
V4L/DVB (6133): tuner-simple: convert from tuner sub-driver into dvb_frontend module
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Acked-by: Mike Isely <isely@pobox.com> Acked-by: Steven Toth <stoth@hauppauge.com> Acked-by: Patrick Boettcher <pb@linuxtv.org> Acked-by: Jarod Wilson <jwilson@redhat.com> Acked-by: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tuner-core.c17
-rw-r--r--drivers/media/video/tuner-driver.h2
-rw-r--r--drivers/media/video/tuner-simple.c294
-rw-r--r--drivers/media/video/tuner-simple.h35
4 files changed, 236 insertions, 112 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 9598a3da85f4..8ee0be261076 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -17,12 +17,14 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/videodev.h> 18#include <linux/videodev.h>
19#include <media/tuner.h> 19#include <media/tuner.h>
20#include <media/tuner-types.h>
20#include <media/v4l2-common.h> 21#include <media/v4l2-common.h>
21#include "tuner-driver.h" 22#include "tuner-driver.h"
22#include "mt20xx.h" 23#include "mt20xx.h"
23#include "tda8290.h" 24#include "tda8290.h"
24#include "tea5761.h" 25#include "tea5761.h"
25#include "tea5767.h" 26#include "tea5767.h"
27#include "tuner-simple.h"
26 28
27#define UNSET (-1U) 29#define UNSET (-1U)
28 30
@@ -213,6 +215,15 @@ static void attach_tda8290(struct tuner *t)
213 tda8290_attach(&t->fe, t->i2c.adapter, t->i2c.addr, &cfg); 215 tda8290_attach(&t->fe, t->i2c.adapter, t->i2c.addr, &cfg);
214} 216}
215 217
218static void attach_simple_tuner(struct tuner *t)
219{
220 struct simple_tuner_config cfg = {
221 .type = t->type,
222 .tun = &tuners[t->type]
223 };
224 simple_tuner_attach(&t->fe, t->i2c.adapter, t->i2c.addr, &cfg);
225}
226
216static void set_type(struct i2c_client *c, unsigned int type, 227static void set_type(struct i2c_client *c, unsigned int type,
217 unsigned int new_mode_mask, unsigned int new_config, 228 unsigned int new_mode_mask, unsigned int new_config,
218 int (*tuner_callback) (void *dev, int command,int arg)) 229 int (*tuner_callback) (void *dev, int command,int arg))
@@ -290,7 +301,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
290 buffer[2] = 0x86; 301 buffer[2] = 0x86;
291 buffer[3] = 0x54; 302 buffer[3] = 0x54;
292 i2c_master_send(c, buffer, 4); 303 i2c_master_send(c, buffer, 4);
293 default_tuner_init(t); 304 attach_simple_tuner(t);
294 break; 305 break;
295 case TUNER_PHILIPS_TD1316: 306 case TUNER_PHILIPS_TD1316:
296 buffer[0] = 0x0b; 307 buffer[0] = 0x0b;
@@ -298,13 +309,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
298 buffer[2] = 0x86; 309 buffer[2] = 0x86;
299 buffer[3] = 0xa4; 310 buffer[3] = 0xa4;
300 i2c_master_send(c,buffer,4); 311 i2c_master_send(c,buffer,4);
301 default_tuner_init(t); 312 attach_simple_tuner(t);
302 break; 313 break;
303 case TUNER_TDA9887: 314 case TUNER_TDA9887:
304 tda9887_tuner_init(t); 315 tda9887_tuner_init(t);
305 break; 316 break;
306 default: 317 default:
307 default_tuner_init(t); 318 attach_simple_tuner(t);
308 break; 319 break;
309 } 320 }
310 321
diff --git a/drivers/media/video/tuner-driver.h b/drivers/media/video/tuner-driver.h
index 664f3467ee4f..28a10da76d12 100644
--- a/drivers/media/video/tuner-driver.h
+++ b/drivers/media/video/tuner-driver.h
@@ -72,8 +72,6 @@ struct tuner {
72 72
73/* ------------------------------------------------------------------------ */ 73/* ------------------------------------------------------------------------ */
74 74
75extern int default_tuner_init(struct tuner *t);
76
77extern int tda9887_tuner_init(struct tuner *t); 75extern int tda9887_tuner_init(struct tuner *t);
78 76
79/* ------------------------------------------------------------------------ */ 77/* ------------------------------------------------------------------------ */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index eca2ff249a36..2dbd91c8cb64 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,7 +1,8 @@
1/* 1/*
2 *
3 * i2c tv tuner chip device driver 2 * i2c tv tuner chip device driver
4 * controls all those simple 4-control-bytes style tuners. 3 * controls all those simple 4-control-bytes style tuners.
4 *
5 * This "tuner-simple" module was split apart from the original "tuner" module.
5 */ 6 */
6#include <linux/delay.h> 7#include <linux/delay.h>
7#include <linux/i2c.h> 8#include <linux/i2c.h>
@@ -9,7 +10,14 @@
9#include <media/tuner.h> 10#include <media/tuner.h>
10#include <media/v4l2-common.h> 11#include <media/v4l2-common.h>
11#include <media/tuner-types.h> 12#include <media/tuner-types.h>
12#include "tuner-driver.h" 13#include "tuner-i2c.h"
14#include "tuner-simple.h"
15
16static int debug = 0;
17module_param(debug, int, 0644);
18MODULE_PARM_DESC(debug, "enable verbose debug messages");
19
20#define PREFIX "tuner-simple "
13 21
14static int offset = 0; 22static int offset = 0;
15module_param(offset, int, 0664); 23module_param(offset, int, 0664);
@@ -85,13 +93,18 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
85struct tuner_simple_priv { 93struct tuner_simple_priv {
86 u16 last_div; 94 u16 last_div;
87 struct tuner_i2c_props i2c_props; 95 struct tuner_i2c_props i2c_props;
96
97 unsigned int type;
98 struct tunertype *tun;
99
100 u32 frequency;
88}; 101};
89 102
90/* ---------------------------------------------------------------------- */ 103/* ---------------------------------------------------------------------- */
91 104
92static int tuner_getstatus(struct tuner *t) 105static int tuner_getstatus(struct dvb_frontend *fe)
93{ 106{
94 struct tuner_simple_priv *priv = t->priv; 107 struct tuner_simple_priv *priv = fe->tuner_priv;
95 unsigned char byte; 108 unsigned char byte;
96 109
97 if (1 != tuner_i2c_xfer_recv(&priv->i2c_props,&byte,1)) 110 if (1 != tuner_i2c_xfer_recv(&priv->i2c_props,&byte,1))
@@ -100,18 +113,20 @@ static int tuner_getstatus(struct tuner *t)
100 return byte; 113 return byte;
101} 114}
102 115
103static int tuner_signal(struct tuner *t) 116static int tuner_signal(struct dvb_frontend *fe)
104{ 117{
105 return (tuner_getstatus(t) & TUNER_SIGNAL) << 13; 118 return (tuner_getstatus(fe) & TUNER_SIGNAL) << 13;
106} 119}
107 120
108static int tuner_stereo(struct tuner *t) 121static int tuner_stereo(struct dvb_frontend *fe)
109{ 122{
123 struct tuner_simple_priv *priv = fe->tuner_priv;
124
110 int stereo, status; 125 int stereo, status;
111 126
112 status = tuner_getstatus(t); 127 status = tuner_getstatus(fe);
113 128
114 switch (t->type) { 129 switch (priv->type) {
115 case TUNER_PHILIPS_FM1216ME_MK3: 130 case TUNER_PHILIPS_FM1216ME_MK3:
116 case TUNER_PHILIPS_FM1236_MK3: 131 case TUNER_PHILIPS_FM1236_MK3:
117 case TUNER_PHILIPS_FM1256_IH3: 132 case TUNER_PHILIPS_FM1256_IH3:
@@ -126,20 +141,38 @@ static int tuner_stereo(struct tuner *t)
126} 141}
127 142
128 143
144static int simple_get_status(struct dvb_frontend *fe, u32 *status)
145{
146 struct tuner_simple_priv *priv = fe->tuner_priv;
147 int signal = tuner_signal(fe);
148
149 *status = 0;
150
151 if (signal)
152 *status = TUNER_STATUS_LOCKED;
153 if (tuner_stereo(fe))
154 *status |= TUNER_STATUS_STEREO;
155
156 tuner_dbg("tuner-simple: Signal strength: %d\n", signal);
157
158 return 0;
159}
160
129/* ---------------------------------------------------------------------- */ 161/* ---------------------------------------------------------------------- */
130 162
131static void default_set_tv_freq(struct tuner *t, unsigned int freq) 163static int simple_set_tv_freq(struct dvb_frontend *fe,
164 struct analog_parameters *params)
132{ 165{
133 struct tuner_simple_priv *priv = t->priv; 166 struct tuner_simple_priv *priv = fe->tuner_priv;
134 u8 config, cb, tuneraddr; 167 u8 config, cb, tuneraddr;
135 u16 div; 168 u16 div;
136 struct tunertype *tun; 169 struct tunertype *tun;
137 u8 buffer[4]; 170 u8 buffer[4];
138 int rc, IFPCoff, i, j; 171 int rc, IFPCoff, i, j;
139 enum param_type desired_type; 172 enum param_type desired_type;
140 struct tuner_params *params; 173 struct tuner_params *t_params;
141 174
142 tun = &tuners[t->type]; 175 tun = priv->tun;
143 176
144 /* IFPCoff = Video Intermediate Frequency - Vif: 177 /* IFPCoff = Video Intermediate Frequency - Vif:
145 940 =16*58.75 NTSC/J (Japan) 178 940 =16*58.75 NTSC/J (Japan)
@@ -153,14 +186,14 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
153 171.2=16*10.70 FM Radio (at set_radio_freq) 186 171.2=16*10.70 FM Radio (at set_radio_freq)
154 */ 187 */
155 188
156 if (t->std == V4L2_STD_NTSC_M_JP) { 189 if (params->std == V4L2_STD_NTSC_M_JP) {
157 IFPCoff = 940; 190 IFPCoff = 940;
158 desired_type = TUNER_PARAM_TYPE_NTSC; 191 desired_type = TUNER_PARAM_TYPE_NTSC;
159 } else if ((t->std & V4L2_STD_MN) && 192 } else if ((params->std & V4L2_STD_MN) &&
160 !(t->std & ~V4L2_STD_MN)) { 193 !(params->std & ~V4L2_STD_MN)) {
161 IFPCoff = 732; 194 IFPCoff = 732;
162 desired_type = TUNER_PARAM_TYPE_NTSC; 195 desired_type = TUNER_PARAM_TYPE_NTSC;
163 } else if (t->std == V4L2_STD_SECAM_LC) { 196 } else if (params->std == V4L2_STD_SECAM_LC) {
164 IFPCoff = 543; 197 IFPCoff = 543;
165 desired_type = TUNER_PARAM_TYPE_SECAM; 198 desired_type = TUNER_PARAM_TYPE_SECAM;
166 } else { 199 } else {
@@ -173,49 +206,49 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
173 continue; 206 continue;
174 break; 207 break;
175 } 208 }
176 /* use default tuner_params if desired_type not available */ 209 /* use default tuner_t_params if desired_type not available */
177 if (desired_type != tun->params[j].type) { 210 if (desired_type != tun->params[j].type) {
178 tuner_dbg("IFPCoff = %d: tuner_params undefined for tuner %d\n", 211 tuner_dbg("IFPCoff = %d: tuner_t_params undefined for tuner %d\n",
179 IFPCoff,t->type); 212 IFPCoff, priv->type);
180 j = 0; 213 j = 0;
181 } 214 }
182 params = &tun->params[j]; 215 t_params = &tun->params[j];
183 216
184 for (i = 0; i < params->count; i++) { 217 for (i = 0; i < t_params->count; i++) {
185 if (freq > params->ranges[i].limit) 218 if (params->frequency > t_params->ranges[i].limit)
186 continue; 219 continue;
187 break; 220 break;
188 } 221 }
189 if (i == params->count) { 222 if (i == t_params->count) {
190 tuner_dbg("TV frequency out of range (%d > %d)", 223 tuner_dbg("TV frequency out of range (%d > %d)",
191 freq, params->ranges[i - 1].limit); 224 params->frequency, t_params->ranges[i - 1].limit);
192 freq = params->ranges[--i].limit; 225 params->frequency = t_params->ranges[--i].limit;
193 } 226 }
194 config = params->ranges[i].config; 227 config = t_params->ranges[i].config;
195 cb = params->ranges[i].cb; 228 cb = t_params->ranges[i].cb;
196 /* i == 0 -> VHF_LO 229 /* i == 0 -> VHF_LO
197 * i == 1 -> VHF_HI 230 * i == 1 -> VHF_HI
198 * i == 2 -> UHF */ 231 * i == 2 -> UHF */
199 tuner_dbg("tv: param %d, range %d\n",j,i); 232 tuner_dbg("tv: param %d, range %d\n",j,i);
200 233
201 div=freq + IFPCoff + offset; 234 div=params->frequency + IFPCoff + offset;
202 235
203 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", 236 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
204 freq / 16, freq % 16 * 100 / 16, 237 params->frequency / 16, params->frequency % 16 * 100 / 16,
205 IFPCoff / 16, IFPCoff % 16 * 100 / 16, 238 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
206 offset / 16, offset % 16 * 100 / 16, 239 offset / 16, offset % 16 * 100 / 16,
207 div); 240 div);
208 241
209 /* tv norm specific stuff for multi-norm tuners */ 242 /* tv norm specific stuff for multi-norm tuners */
210 switch (t->type) { 243 switch (priv->type) {
211 case TUNER_PHILIPS_SECAM: // FI1216MF 244 case TUNER_PHILIPS_SECAM: // FI1216MF
212 /* 0x01 -> ??? no change ??? */ 245 /* 0x01 -> ??? no change ??? */
213 /* 0x02 -> PAL BDGHI / SECAM L */ 246 /* 0x02 -> PAL BDGHI / SECAM L */
214 /* 0x04 -> ??? PAL others / SECAM others ??? */ 247 /* 0x04 -> ??? PAL others / SECAM others ??? */
215 cb &= ~0x03; 248 cb &= ~0x03;
216 if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM 249 if (params->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM
217 cb |= PHILIPS_MF_SET_STD_L; 250 cb |= PHILIPS_MF_SET_STD_L;
218 else if (t->std & V4L2_STD_SECAM_LC) 251 else if (params->std & V4L2_STD_SECAM_LC)
219 cb |= PHILIPS_MF_SET_STD_LC; 252 cb |= PHILIPS_MF_SET_STD_LC;
220 else /* V4L2_STD_B|V4L2_STD_GH */ 253 else /* V4L2_STD_B|V4L2_STD_GH */
221 cb |= PHILIPS_MF_SET_STD_BG; 254 cb |= PHILIPS_MF_SET_STD_BG;
@@ -224,16 +257,16 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
224 case TUNER_TEMIC_4046FM5: 257 case TUNER_TEMIC_4046FM5:
225 cb &= ~0x0f; 258 cb &= ~0x0f;
226 259
227 if (t->std & V4L2_STD_PAL_BG) { 260 if (params->std & V4L2_STD_PAL_BG) {
228 cb |= TEMIC_SET_PAL_BG; 261 cb |= TEMIC_SET_PAL_BG;
229 262
230 } else if (t->std & V4L2_STD_PAL_I) { 263 } else if (params->std & V4L2_STD_PAL_I) {
231 cb |= TEMIC_SET_PAL_I; 264 cb |= TEMIC_SET_PAL_I;
232 265
233 } else if (t->std & V4L2_STD_PAL_DK) { 266 } else if (params->std & V4L2_STD_PAL_DK) {
234 cb |= TEMIC_SET_PAL_DK; 267 cb |= TEMIC_SET_PAL_DK;
235 268
236 } else if (t->std & V4L2_STD_SECAM_L) { 269 } else if (params->std & V4L2_STD_SECAM_L) {
237 cb |= TEMIC_SET_PAL_L; 270 cb |= TEMIC_SET_PAL_L;
238 271
239 } 272 }
@@ -242,13 +275,13 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
242 case TUNER_PHILIPS_FQ1216ME: 275 case TUNER_PHILIPS_FQ1216ME:
243 cb &= ~0x0f; 276 cb &= ~0x0f;
244 277
245 if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { 278 if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
246 cb |= PHILIPS_SET_PAL_BGDK; 279 cb |= PHILIPS_SET_PAL_BGDK;
247 280
248 } else if (t->std & V4L2_STD_PAL_I) { 281 } else if (params->std & V4L2_STD_PAL_I) {
249 cb |= PHILIPS_SET_PAL_I; 282 cb |= PHILIPS_SET_PAL_I;
250 283
251 } else if (t->std & V4L2_STD_SECAM_L) { 284 } else if (params->std & V4L2_STD_SECAM_L) {
252 cb |= PHILIPS_SET_PAL_L; 285 cb |= PHILIPS_SET_PAL_L;
253 286
254 } 287 }
@@ -260,7 +293,7 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
260 /* 0x02 -> NTSC antenna input 1 */ 293 /* 0x02 -> NTSC antenna input 1 */
261 /* 0x03 -> NTSC antenna input 2 */ 294 /* 0x03 -> NTSC antenna input 2 */
262 cb &= ~0x03; 295 cb &= ~0x03;
263 if (!(t->std & V4L2_STD_ATSC)) 296 if (!(params->std & V4L2_STD_ATSC))
264 cb |= 2; 297 cb |= 2;
265 /* FIXME: input */ 298 /* FIXME: input */
266 break; 299 break;
@@ -280,7 +313,7 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
280 buffer[2] = 0x17; 313 buffer[2] = 0x17;
281 buffer[3] = 0x00; 314 buffer[3] = 0x00;
282 cb &= ~0x40; 315 cb &= ~0x40;
283 if (t->std & V4L2_STD_ATSC) { 316 if (params->std & V4L2_STD_ATSC) {
284 cb |= 0x40; 317 cb |= 0x40;
285 buffer[1] = 0x04; 318 buffer[1] = 0x04;
286 } 319 }
@@ -296,7 +329,7 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
296 break; 329 break;
297 } 330 }
298 331
299 if (params->cb_first_if_lower_freq && div < priv->last_div) { 332 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
300 buffer[0] = config; 333 buffer[0] = config;
301 buffer[1] = cb; 334 buffer[1] = cb;
302 buffer[2] = (div>>8) & 0x7f; 335 buffer[2] = (div>>8) & 0x7f;
@@ -308,42 +341,42 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
308 buffer[3] = cb; 341 buffer[3] = cb;
309 } 342 }
310 priv->last_div = div; 343 priv->last_div = div;
311 if (params->has_tda9887) { 344 if (t_params->has_tda9887) {
312 int config = 0; 345 int config = 0;
313 int is_secam_l = (t->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) && 346 int is_secam_l = (params->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) &&
314 !(t->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)); 347 !(params->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC));
315 348
316 if (t->std == V4L2_STD_SECAM_LC) { 349 if (params->std == V4L2_STD_SECAM_LC) {
317 if (params->port1_active ^ params->port1_invert_for_secam_lc) 350 if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
318 config |= TDA9887_PORT1_ACTIVE; 351 config |= TDA9887_PORT1_ACTIVE;
319 if (params->port2_active ^ params->port2_invert_for_secam_lc) 352 if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
320 config |= TDA9887_PORT2_ACTIVE; 353 config |= TDA9887_PORT2_ACTIVE;
321 } 354 }
322 else { 355 else {
323 if (params->port1_active) 356 if (t_params->port1_active)
324 config |= TDA9887_PORT1_ACTIVE; 357 config |= TDA9887_PORT1_ACTIVE;
325 if (params->port2_active) 358 if (t_params->port2_active)
326 config |= TDA9887_PORT2_ACTIVE; 359 config |= TDA9887_PORT2_ACTIVE;
327 } 360 }
328 if (params->intercarrier_mode) 361 if (t_params->intercarrier_mode)
329 config |= TDA9887_INTERCARRIER; 362 config |= TDA9887_INTERCARRIER;
330 if (is_secam_l) { 363 if (is_secam_l) {
331 if (i == 0 && params->default_top_secam_low) 364 if (i == 0 && t_params->default_top_secam_low)
332 config |= TDA9887_TOP(params->default_top_secam_low); 365 config |= TDA9887_TOP(t_params->default_top_secam_low);
333 else if (i == 1 && params->default_top_secam_mid) 366 else if (i == 1 && t_params->default_top_secam_mid)
334 config |= TDA9887_TOP(params->default_top_secam_mid); 367 config |= TDA9887_TOP(t_params->default_top_secam_mid);
335 else if (params->default_top_secam_high) 368 else if (t_params->default_top_secam_high)
336 config |= TDA9887_TOP(params->default_top_secam_high); 369 config |= TDA9887_TOP(t_params->default_top_secam_high);
337 } 370 }
338 else { 371 else {
339 if (i == 0 && params->default_top_low) 372 if (i == 0 && t_params->default_top_low)
340 config |= TDA9887_TOP(params->default_top_low); 373 config |= TDA9887_TOP(t_params->default_top_low);
341 else if (i == 1 && params->default_top_mid) 374 else if (i == 1 && t_params->default_top_mid)
342 config |= TDA9887_TOP(params->default_top_mid); 375 config |= TDA9887_TOP(t_params->default_top_mid);
343 else if (params->default_top_high) 376 else if (t_params->default_top_high)
344 config |= TDA9887_TOP(params->default_top_high); 377 config |= TDA9887_TOP(t_params->default_top_high);
345 } 378 }
346 if (params->default_pll_gating_18) 379 if (t_params->default_pll_gating_18)
347 config |= TDA9887_GATING_18; 380 config |= TDA9887_GATING_18;
348 i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config); 381 i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config);
349 } 382 }
@@ -353,7 +386,7 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
353 if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) 386 if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4)))
354 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 387 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
355 388
356 switch (t->type) { 389 switch (priv->type) {
357 case TUNER_LG_TDVS_H06XF: 390 case TUNER_LG_TDVS_H06XF:
358 /* Set the Auxiliary Byte. */ 391 /* Set the Auxiliary Byte. */
359 buffer[0] = buffer[2]; 392 buffer[0] = buffer[2];
@@ -374,7 +407,7 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
374 /* Wait until the PLL locks */ 407 /* Wait until the PLL locks */
375 for (;;) { 408 for (;;) {
376 if (time_after(jiffies,timeout)) 409 if (time_after(jiffies,timeout))
377 return; 410 return 0;
378 if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,&status_byte,1))) { 411 if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,&status_byte,1))) {
379 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc); 412 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
380 break; 413 break;
@@ -398,27 +431,30 @@ static void default_set_tv_freq(struct tuner *t, unsigned int freq)
398 break; 431 break;
399 } 432 }
400 } 433 }
434 return 0;
401} 435}
402 436
403static void default_set_radio_freq(struct tuner *t, unsigned int freq) 437static int simple_set_radio_freq(struct dvb_frontend *fe,
438 struct analog_parameters *params)
404{ 439{
405 struct tunertype *tun; 440 struct tunertype *tun;
406 struct tuner_simple_priv *priv = t->priv; 441 struct tuner_simple_priv *priv = fe->tuner_priv;
407 u8 buffer[4]; 442 u8 buffer[4];
408 u16 div; 443 u16 div;
409 int rc, j; 444 int rc, j;
410 struct tuner_params *params; 445 struct tuner_params *t_params;
446 unsigned int freq = params->frequency;
411 447
412 tun = &tuners[t->type]; 448 tun = priv->tun;
413 449
414 for (j = tun->count-1; j > 0; j--) 450 for (j = tun->count-1; j > 0; j--)
415 if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO) 451 if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
416 break; 452 break;
417 /* default params (j=0) will be used if desired type wasn't found */ 453 /* default t_params (j=0) will be used if desired type wasn't found */
418 params = &tun->params[j]; 454 t_params = &tun->params[j];
419 455
420 /* Select Radio 1st IF used */ 456 /* Select Radio 1st IF used */
421 switch (params->radio_if) { 457 switch (t_params->radio_if) {
422 case 0: /* 10.7 MHz */ 458 case 0: /* 10.7 MHz */
423 freq += (unsigned int)(10.7*16000); 459 freq += (unsigned int)(10.7*16000);
424 break; 460 break;
@@ -429,16 +465,16 @@ static void default_set_radio_freq(struct tuner *t, unsigned int freq)
429 freq += (unsigned int)(41.3*16000); 465 freq += (unsigned int)(41.3*16000);
430 break; 466 break;
431 default: 467 default:
432 tuner_warn("Unsupported radio_if value %d\n", params->radio_if); 468 tuner_warn("Unsupported radio_if value %d\n", t_params->radio_if);
433 return; 469 return 0;
434 } 470 }
435 471
436 /* Bandswitch byte */ 472 /* Bandswitch byte */
437 switch (t->type) { 473 switch (priv->type) {
438 case TUNER_TENA_9533_DI: 474 case TUNER_TENA_9533_DI:
439 case TUNER_YMEC_TVF_5533MF: 475 case TUNER_YMEC_TVF_5533MF:
440 tuner_dbg ("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n"); 476 tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n");
441 return; 477 return 0;
442 case TUNER_PHILIPS_FM1216ME_MK3: 478 case TUNER_PHILIPS_FM1216ME_MK3:
443 case TUNER_PHILIPS_FM1236_MK3: 479 case TUNER_PHILIPS_FM1236_MK3:
444 case TUNER_PHILIPS_FMD1216ME_MK3: 480 case TUNER_PHILIPS_FMD1216ME_MK3:
@@ -461,7 +497,7 @@ static void default_set_radio_freq(struct tuner *t, unsigned int freq)
461 break; 497 break;
462 } 498 }
463 499
464 buffer[2] = (params->ranges[0].config & ~TUNER_RATIO_MASK) | 500 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
465 TUNER_RATIO_SELECT_50; /* 50 kHz step */ 501 TUNER_RATIO_SELECT_50; /* 50 kHz step */
466 502
467 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps 503 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
@@ -469,7 +505,7 @@ static void default_set_radio_freq(struct tuner *t, unsigned int freq)
469 freq * (1/800) */ 505 freq * (1/800) */
470 div = (freq + 400) / 800; 506 div = (freq + 400) / 800;
471 507
472 if (params->cb_first_if_lower_freq && div < priv->last_div) { 508 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
473 buffer[0] = buffer[2]; 509 buffer[0] = buffer[2];
474 buffer[1] = buffer[3]; 510 buffer[1] = buffer[3];
475 buffer[2] = (div>>8) & 0x7f; 511 buffer[2] = (div>>8) & 0x7f;
@@ -483,61 +519,105 @@ static void default_set_radio_freq(struct tuner *t, unsigned int freq)
483 buffer[0],buffer[1],buffer[2],buffer[3]); 519 buffer[0],buffer[1],buffer[2],buffer[3]);
484 priv->last_div = div; 520 priv->last_div = div;
485 521
486 if (params->has_tda9887) { 522 if (t_params->has_tda9887) {
487 int config = 0; 523 int config = 0;
488 if (params->port1_active && !params->port1_fm_high_sensitivity) 524 if (t_params->port1_active && !t_params->port1_fm_high_sensitivity)
489 config |= TDA9887_PORT1_ACTIVE; 525 config |= TDA9887_PORT1_ACTIVE;
490 if (params->port2_active && !params->port2_fm_high_sensitivity) 526 if (t_params->port2_active && !t_params->port2_fm_high_sensitivity)
491 config |= TDA9887_PORT2_ACTIVE; 527 config |= TDA9887_PORT2_ACTIVE;
492 if (params->intercarrier_mode) 528 if (t_params->intercarrier_mode)
493 config |= TDA9887_INTERCARRIER; 529 config |= TDA9887_INTERCARRIER;
494/* if (params->port1_set_for_fm_mono) 530/* if (t_params->port1_set_for_fm_mono)
495 config &= ~TDA9887_PORT1_ACTIVE;*/ 531 config &= ~TDA9887_PORT1_ACTIVE;*/
496 if (params->fm_gain_normal) 532 if (t_params->fm_gain_normal)
497 config |= TDA9887_GAIN_NORMAL; 533 config |= TDA9887_GAIN_NORMAL;
498 if (params->radio_if == 2) 534 if (t_params->radio_if == 2)
499 config |= TDA9887_RIF_41_3; 535 config |= TDA9887_RIF_41_3;
500 i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config); 536 i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config);
501 } 537 }
502 if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) 538 if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4)))
503 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 539 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
540
541 return 0;
504} 542}
505 543
506static void tuner_release(struct tuner *t) 544static int simple_set_params(struct dvb_frontend *fe,
545 struct analog_parameters *params)
507{ 546{
508 kfree(t->priv); 547 struct tuner_simple_priv *priv = fe->tuner_priv;
509 t->priv = NULL; 548 int ret = -EINVAL;
549
550 switch (params->mode) {
551 case V4L2_TUNER_RADIO:
552 ret = simple_set_radio_freq(fe, params);
553 priv->frequency = params->frequency * 125 / 2;
554 break;
555 case V4L2_TUNER_ANALOG_TV:
556 case V4L2_TUNER_DIGITAL_TV:
557 ret = simple_set_tv_freq(fe, params);
558 priv->frequency = params->frequency * 62500;
559 break;
560 }
561
562 return ret;
563}
564
565
566static int simple_release(struct dvb_frontend *fe)
567{
568 kfree(fe->tuner_priv);
569 fe->tuner_priv = NULL;
570
571 return 0;
572}
573
574static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
575{
576 struct tuner_simple_priv *priv = fe->tuner_priv;
577 *frequency = priv->frequency;
578 return 0;
510} 579}
511 580
512static struct tuner_operations simple_tuner_ops = { 581static struct dvb_tuner_ops simple_tuner_ops = {
513 .set_tv_freq = default_set_tv_freq, 582 .set_analog_params = simple_set_params,
514 .set_radio_freq = default_set_radio_freq, 583 .release = simple_release,
515 .has_signal = tuner_signal, 584 .get_frequency = simple_get_frequency,
516 .is_stereo = tuner_stereo, 585 .get_status = simple_get_status,
517 .release = tuner_release,
518}; 586};
519 587
520int default_tuner_init(struct tuner *t) 588struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
589 struct i2c_adapter *i2c_adap,
590 u8 i2c_addr,
591 struct simple_tuner_config *cfg)
521{ 592{
522 struct tuner_simple_priv *priv = NULL; 593 struct tuner_simple_priv *priv = NULL;
523 594
524 priv = kzalloc(sizeof(struct tuner_simple_priv), GFP_KERNEL); 595 priv = kzalloc(sizeof(struct tuner_simple_priv), GFP_KERNEL);
525 if (priv == NULL) 596 if (priv == NULL)
526 return -ENOMEM; 597 return NULL;
527 t->priv = priv; 598 fe->tuner_priv = priv;
528 599
529 priv->i2c_props.addr = t->i2c.addr; 600 priv->i2c_props.addr = i2c_addr;
530 priv->i2c_props.adap = t->i2c.adapter; 601 priv->i2c_props.adap = i2c_adap;
602 priv->type = cfg->type;
603 priv->tun = cfg->tun;
531 604
532 tuner_info("type set to %d (%s)\n", 605 memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, sizeof(struct dvb_tuner_ops));
533 t->type, tuners[t->type].name);
534 strlcpy(t->i2c.name, tuners[t->type].name, sizeof(t->i2c.name));
535 606
536 memcpy(&t->ops, &simple_tuner_ops, sizeof(struct tuner_operations)); 607 tuner_info("type set to %d (%s)\n", cfg->type, cfg->tun->name);
537 608
538 return 0; 609 strlcpy(fe->ops.tuner_ops.info.name, cfg->tun->name, sizeof(fe->ops.tuner_ops.info.name));
610
611 return fe;
539} 612}
540 613
614
615EXPORT_SYMBOL_GPL(simple_tuner_attach);
616
617MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
618MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
619MODULE_LICENSE("GPL");
620
541/* 621/*
542 * Overrides for Emacs so that we follow Linus's tabbing style. 622 * Overrides for Emacs so that we follow Linus's tabbing style.
543 * --------------------------------------------------------------------------- 623 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/video/tuner-simple.h
new file mode 100644
index 000000000000..75cd45b7145d
--- /dev/null
+++ b/drivers/media/video/tuner-simple.h
@@ -0,0 +1,35 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TUNER_SIMPLE_H__
18#define __TUNER_SIMPLE_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23struct simple_tuner_config
24{
25 /* chip type */
26 unsigned int type;
27 struct tunertype *tun;
28};
29
30extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
31 struct i2c_adapter *i2c_adap,
32 u8 i2c_addr,
33 struct simple_tuner_config *cfg);
34
35#endif /* __TUNER_SIMPLE_H__ */