diff options
author | Michael Krufky <mkrufky@linuxtv.org> | 2007-08-27 20:59:08 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:07:41 -0400 |
commit | 4adad287de82703fd504fdab7aebe760196bb786 (patch) | |
tree | abdb6772db2f03e6d914c6a5c9b060fbd33fff84 /drivers/media | |
parent | 8d0936ed15f509c32e8f81849be3a1cee80e2225 (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.c | 17 | ||||
-rw-r--r-- | drivers/media/video/tuner-driver.h | 2 | ||||
-rw-r--r-- | drivers/media/video/tuner-simple.c | 294 | ||||
-rw-r--r-- | drivers/media/video/tuner-simple.h | 35 |
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 | ||
218 | static 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 | |||
216 | static void set_type(struct i2c_client *c, unsigned int type, | 227 | static 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 | ||
75 | extern int default_tuner_init(struct tuner *t); | ||
76 | |||
77 | extern int tda9887_tuner_init(struct tuner *t); | 75 | extern 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 | |||
16 | static int debug = 0; | ||
17 | module_param(debug, int, 0644); | ||
18 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
19 | |||
20 | #define PREFIX "tuner-simple " | ||
13 | 21 | ||
14 | static int offset = 0; | 22 | static int offset = 0; |
15 | module_param(offset, int, 0664); | 23 | module_param(offset, int, 0664); |
@@ -85,13 +93,18 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | |||
85 | struct tuner_simple_priv { | 93 | struct 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 | ||
92 | static int tuner_getstatus(struct tuner *t) | 105 | static 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 | ||
103 | static int tuner_signal(struct tuner *t) | 116 | static 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 | ||
108 | static int tuner_stereo(struct tuner *t) | 121 | static 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 | ||
144 | static 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 | ||
131 | static void default_set_tv_freq(struct tuner *t, unsigned int freq) | 163 | static 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 | ||
403 | static void default_set_radio_freq(struct tuner *t, unsigned int freq) | 437 | static 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 | ||
506 | static void tuner_release(struct tuner *t) | 544 | static 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 | |||
566 | static int simple_release(struct dvb_frontend *fe) | ||
567 | { | ||
568 | kfree(fe->tuner_priv); | ||
569 | fe->tuner_priv = NULL; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static 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 | ||
512 | static struct tuner_operations simple_tuner_ops = { | 581 | static 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 | ||
520 | int default_tuner_init(struct tuner *t) | 588 | struct 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 | |||
615 | EXPORT_SYMBOL_GPL(simple_tuner_attach); | ||
616 | |||
617 | MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver"); | ||
618 | MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | ||
619 | MODULE_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 | |||
23 | struct simple_tuner_config | ||
24 | { | ||
25 | /* chip type */ | ||
26 | unsigned int type; | ||
27 | struct tunertype *tun; | ||
28 | }; | ||
29 | |||
30 | extern 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__ */ | ||