Commit 8340ff43c49fe8e0cd049b65fbd2156bd651697e
Committed by
Mauro Carvalho Chehab
1 parent
2b80a19181
Exists in
master
and in
4 other branches
V4L/DVB (10863): saa7191: convert to v4l2_subdev.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Showing 2 changed files with 129 additions and 114 deletions Side-by-side Diff
drivers/media/video/saa7191.c
... | ... | @@ -21,7 +21,8 @@ |
21 | 21 | |
22 | 22 | #include <linux/videodev2.h> |
23 | 23 | #include <linux/i2c.h> |
24 | -#include <media/v4l2-common.h> | |
24 | +#include <media/v4l2-device.h> | |
25 | +#include <media/v4l2-chip-ident.h> | |
25 | 26 | #include <media/v4l2-i2c-drv-legacy.h> |
26 | 27 | |
27 | 28 | #include "saa7191.h" |
... | ... | @@ -49,7 +50,7 @@ |
49 | 50 | #define SAA7191_SYNC_DELAY 100 /* milliseconds */ |
50 | 51 | |
51 | 52 | struct saa7191 { |
52 | - struct i2c_client *client; | |
53 | + struct v4l2_subdev sd; | |
53 | 54 | |
54 | 55 | /* the register values are stored here as the actual |
55 | 56 | * I2C-registers are write-only */ |
... | ... | @@ -59,6 +60,11 @@ |
59 | 60 | v4l2_std_id norm; |
60 | 61 | }; |
61 | 62 | |
63 | +static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd) | |
64 | +{ | |
65 | + return container_of(sd, struct saa7191, sd); | |
66 | +} | |
67 | + | |
62 | 68 | static const u8 initseq[] = { |
63 | 69 | 0, /* Subaddress */ |
64 | 70 | |
65 | 71 | |
66 | 72 | |
67 | 73 | |
... | ... | @@ -103,15 +109,14 @@ |
103 | 109 | |
104 | 110 | /* SAA7191 register handling */ |
105 | 111 | |
106 | -static u8 saa7191_read_reg(struct i2c_client *client, | |
107 | - u8 reg) | |
112 | +static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg) | |
108 | 113 | { |
109 | - return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg]; | |
114 | + return to_saa7191(sd)->reg[reg]; | |
110 | 115 | } |
111 | 116 | |
112 | -static int saa7191_read_status(struct i2c_client *client, | |
113 | - u8 *value) | |
117 | +static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value) | |
114 | 118 | { |
119 | + struct i2c_client *client = v4l2_get_subdevdata(sd); | |
115 | 120 | int ret; |
116 | 121 | |
117 | 122 | ret = i2c_master_recv(client, value, 1); |
118 | 123 | |
119 | 124 | |
120 | 125 | |
121 | 126 | |
... | ... | @@ -124,21 +129,23 @@ |
124 | 129 | } |
125 | 130 | |
126 | 131 | |
127 | -static int saa7191_write_reg(struct i2c_client *client, u8 reg, | |
128 | - u8 value) | |
132 | +static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) | |
129 | 133 | { |
130 | - ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value; | |
134 | + struct i2c_client *client = v4l2_get_subdevdata(sd); | |
135 | + | |
136 | + to_saa7191(sd)->reg[reg] = value; | |
131 | 137 | return i2c_smbus_write_byte_data(client, reg, value); |
132 | 138 | } |
133 | 139 | |
134 | 140 | /* the first byte of data must be the first subaddress number (register) */ |
135 | -static int saa7191_write_block(struct i2c_client *client, | |
141 | +static int saa7191_write_block(struct v4l2_subdev *sd, | |
136 | 142 | u8 length, const u8 *data) |
137 | 143 | { |
144 | + struct i2c_client *client = v4l2_get_subdevdata(sd); | |
145 | + struct saa7191 *decoder = to_saa7191(sd); | |
138 | 146 | int i; |
139 | 147 | int ret; |
140 | 148 | |
141 | - struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client); | |
142 | 149 | for (i = 0; i < (length - 1); i++) { |
143 | 150 | decoder->reg[data[0] + i] = data[i + 1]; |
144 | 151 | } |
145 | 152 | |
146 | 153 | |
... | ... | @@ -155,14 +162,15 @@ |
155 | 162 | |
156 | 163 | /* Helper functions */ |
157 | 164 | |
158 | -static int saa7191_set_input(struct i2c_client *client, int input) | |
165 | +static int saa7191_s_routing(struct v4l2_subdev *sd, | |
166 | + const struct v4l2_routing *route) | |
159 | 167 | { |
160 | - struct saa7191 *decoder = i2c_get_clientdata(client); | |
161 | - u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA); | |
162 | - u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK); | |
168 | + struct saa7191 *decoder = to_saa7191(sd); | |
169 | + u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA); | |
170 | + u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK); | |
163 | 171 | int err; |
164 | 172 | |
165 | - switch (input) { | |
173 | + switch (route->input) { | |
166 | 174 | case SAA7191_INPUT_COMPOSITE: /* Set Composite input */ |
167 | 175 | iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1 |
168 | 176 | | SAA7191_IOCK_GPSW2); |
169 | 177 | |
170 | 178 | |
171 | 179 | |
172 | 180 | |
... | ... | @@ -178,24 +186,24 @@ |
178 | 186 | return -EINVAL; |
179 | 187 | } |
180 | 188 | |
181 | - err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma); | |
189 | + err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma); | |
182 | 190 | if (err) |
183 | 191 | return -EIO; |
184 | - err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock); | |
192 | + err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock); | |
185 | 193 | if (err) |
186 | 194 | return -EIO; |
187 | 195 | |
188 | - decoder->input = input; | |
196 | + decoder->input = route->input; | |
189 | 197 | |
190 | 198 | return 0; |
191 | 199 | } |
192 | 200 | |
193 | -static int saa7191_set_norm(struct i2c_client *client, v4l2_std_id norm) | |
201 | +static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) | |
194 | 202 | { |
195 | - struct saa7191 *decoder = i2c_get_clientdata(client); | |
196 | - u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); | |
197 | - u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); | |
198 | - u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); | |
203 | + struct saa7191 *decoder = to_saa7191(sd); | |
204 | + u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); | |
205 | + u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); | |
206 | + u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV); | |
199 | 207 | int err; |
200 | 208 | |
201 | 209 | if (norm & V4L2_STD_PAL) { |
202 | 210 | |
203 | 211 | |
... | ... | @@ -215,13 +223,13 @@ |
215 | 223 | return -EINVAL; |
216 | 224 | } |
217 | 225 | |
218 | - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); | |
226 | + err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); | |
219 | 227 | if (err) |
220 | 228 | return -EIO; |
221 | - err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); | |
229 | + err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); | |
222 | 230 | if (err) |
223 | 231 | return -EIO; |
224 | - err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv); | |
232 | + err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv); | |
225 | 233 | if (err) |
226 | 234 | return -EIO; |
227 | 235 | |
228 | 236 | |
... | ... | @@ -234,14 +242,14 @@ |
234 | 242 | return 0; |
235 | 243 | } |
236 | 244 | |
237 | -static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status) | |
245 | +static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status) | |
238 | 246 | { |
239 | 247 | int i = 0; |
240 | 248 | |
241 | 249 | dprintk("Checking for signal...\n"); |
242 | 250 | |
243 | 251 | for (i = 0; i < SAA7191_SYNC_COUNT; i++) { |
244 | - if (saa7191_read_status(client, status)) | |
252 | + if (saa7191_read_status(sd, status)) | |
245 | 253 | return -EIO; |
246 | 254 | |
247 | 255 | if (((*status) & SAA7191_STATUS_HLCK) == 0) { |
248 | 256 | |
... | ... | @@ -257,12 +265,11 @@ |
257 | 265 | return -EBUSY; |
258 | 266 | } |
259 | 267 | |
260 | -static int saa7191_autodetect_norm_extended(struct i2c_client *client, | |
261 | - v4l2_std_id *norm) | |
268 | +static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm) | |
262 | 269 | { |
263 | - struct saa7191 *decoder = i2c_get_clientdata(client); | |
264 | - u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); | |
265 | - u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); | |
270 | + struct saa7191 *decoder = to_saa7191(sd); | |
271 | + u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); | |
272 | + u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); | |
266 | 273 | u8 status; |
267 | 274 | v4l2_std_id old_norm = decoder->norm; |
268 | 275 | int err = 0; |
269 | 276 | |
270 | 277 | |
... | ... | @@ -273,19 +280,19 @@ |
273 | 280 | stdc &= ~SAA7191_STDC_SECS; |
274 | 281 | ctl3 &= ~(SAA7191_CTL3_FSEL); |
275 | 282 | |
276 | - err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); | |
283 | + err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); | |
277 | 284 | if (err) { |
278 | 285 | err = -EIO; |
279 | 286 | goto out; |
280 | 287 | } |
281 | - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); | |
288 | + err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); | |
282 | 289 | if (err) { |
283 | 290 | err = -EIO; |
284 | 291 | goto out; |
285 | 292 | } |
286 | 293 | |
287 | 294 | ctl3 |= SAA7191_CTL3_AUFD; |
288 | - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); | |
295 | + err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); | |
289 | 296 | if (err) { |
290 | 297 | err = -EIO; |
291 | 298 | goto out; |
... | ... | @@ -293,7 +300,7 @@ |
293 | 300 | |
294 | 301 | msleep(SAA7191_SYNC_DELAY); |
295 | 302 | |
296 | - err = saa7191_wait_for_signal(client, &status); | |
303 | + err = saa7191_wait_for_signal(sd, &status); | |
297 | 304 | if (err) |
298 | 305 | goto out; |
299 | 306 | |
300 | 307 | |
301 | 308 | |
302 | 309 | |
303 | 310 | |
304 | 311 | |
... | ... | @@ -308,39 +315,39 @@ |
308 | 315 | dprintk("50Hz signal: Trying PAL...\n"); |
309 | 316 | |
310 | 317 | /* try PAL first */ |
311 | - err = saa7191_set_norm(client, V4L2_STD_PAL); | |
318 | + err = saa7191_s_std(sd, V4L2_STD_PAL); | |
312 | 319 | if (err) |
313 | 320 | goto out; |
314 | 321 | |
315 | 322 | msleep(SAA7191_SYNC_DELAY); |
316 | 323 | |
317 | - err = saa7191_wait_for_signal(client, &status); | |
324 | + err = saa7191_wait_for_signal(sd, &status); | |
318 | 325 | if (err) |
319 | 326 | goto out; |
320 | 327 | |
321 | 328 | /* not 50Hz ? */ |
322 | 329 | if (status & SAA7191_STATUS_FIDT) { |
323 | 330 | dprintk("No 50Hz signal\n"); |
324 | - saa7191_set_norm(client, old_norm); | |
331 | + saa7191_s_std(sd, old_norm); | |
325 | 332 | return -EAGAIN; |
326 | 333 | } |
327 | 334 | |
328 | 335 | if (status & SAA7191_STATUS_CODE) { |
329 | 336 | dprintk("PAL\n"); |
330 | 337 | *norm = V4L2_STD_PAL; |
331 | - return saa7191_set_norm(client, old_norm); | |
338 | + return saa7191_s_std(sd, old_norm); | |
332 | 339 | } |
333 | 340 | |
334 | 341 | dprintk("No color detected with PAL - Trying SECAM...\n"); |
335 | 342 | |
336 | 343 | /* no color detected ? -> try SECAM */ |
337 | - err = saa7191_set_norm(client, V4L2_STD_SECAM); | |
344 | + err = saa7191_s_std(sd, V4L2_STD_SECAM); | |
338 | 345 | if (err) |
339 | 346 | goto out; |
340 | 347 | |
341 | 348 | msleep(SAA7191_SYNC_DELAY); |
342 | 349 | |
343 | - err = saa7191_wait_for_signal(client, &status); | |
350 | + err = saa7191_wait_for_signal(sd, &status); | |
344 | 351 | if (err) |
345 | 352 | goto out; |
346 | 353 | |
347 | 354 | |
348 | 355 | |
... | ... | @@ -355,16 +362,16 @@ |
355 | 362 | /* Color detected -> SECAM */ |
356 | 363 | dprintk("SECAM\n"); |
357 | 364 | *norm = V4L2_STD_SECAM; |
358 | - return saa7191_set_norm(client, old_norm); | |
365 | + return saa7191_s_std(sd, old_norm); | |
359 | 366 | } |
360 | 367 | |
361 | 368 | dprintk("No color detected with SECAM - Going back to PAL.\n"); |
362 | 369 | |
363 | 370 | out: |
364 | - return saa7191_set_norm(client, old_norm); | |
371 | + return saa7191_s_std(sd, old_norm); | |
365 | 372 | } |
366 | 373 | |
367 | -static int saa7191_autodetect_norm(struct i2c_client *client) | |
374 | +static int saa7191_autodetect_norm(struct v4l2_subdev *sd) | |
368 | 375 | { |
369 | 376 | u8 status; |
370 | 377 | |
... | ... | @@ -372,7 +379,7 @@ |
372 | 379 | |
373 | 380 | dprintk("Reading status...\n"); |
374 | 381 | |
375 | - if (saa7191_read_status(client, &status)) | |
382 | + if (saa7191_read_status(sd, &status)) | |
376 | 383 | return -EIO; |
377 | 384 | |
378 | 385 | dprintk("Checking for signal...\n"); |
379 | 386 | |
380 | 387 | |
... | ... | @@ -388,16 +395,15 @@ |
388 | 395 | if (status & SAA7191_STATUS_FIDT) { |
389 | 396 | /* 60hz signal -> NTSC */ |
390 | 397 | dprintk("NTSC\n"); |
391 | - return saa7191_set_norm(client, V4L2_STD_NTSC); | |
398 | + return saa7191_s_std(sd, V4L2_STD_NTSC); | |
392 | 399 | } else { |
393 | 400 | /* 50hz signal -> PAL */ |
394 | 401 | dprintk("PAL\n"); |
395 | - return saa7191_set_norm(client, V4L2_STD_PAL); | |
402 | + return saa7191_s_std(sd, V4L2_STD_PAL); | |
396 | 403 | } |
397 | 404 | } |
398 | 405 | |
399 | -static int saa7191_get_control(struct i2c_client *client, | |
400 | - struct v4l2_control *ctrl) | |
406 | +static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |
401 | 407 | { |
402 | 408 | u8 reg; |
403 | 409 | int ret = 0; |
... | ... | @@ -406,7 +412,7 @@ |
406 | 412 | case SAA7191_CONTROL_BANDPASS: |
407 | 413 | case SAA7191_CONTROL_BANDPASS_WEIGHT: |
408 | 414 | case SAA7191_CONTROL_CORING: |
409 | - reg = saa7191_read_reg(client, SAA7191_REG_LUMA); | |
415 | + reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); | |
410 | 416 | switch (ctrl->id) { |
411 | 417 | case SAA7191_CONTROL_BANDPASS: |
412 | 418 | ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK) |
... | ... | @@ -424,7 +430,7 @@ |
424 | 430 | break; |
425 | 431 | case SAA7191_CONTROL_FORCE_COLOUR: |
426 | 432 | case SAA7191_CONTROL_CHROMA_GAIN: |
427 | - reg = saa7191_read_reg(client, SAA7191_REG_GAIN); | |
433 | + reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); | |
428 | 434 | if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) |
429 | 435 | ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0; |
430 | 436 | else |
... | ... | @@ -432,7 +438,7 @@ |
432 | 438 | >> SAA7191_GAIN_LFIS_SHIFT; |
433 | 439 | break; |
434 | 440 | case V4L2_CID_HUE: |
435 | - reg = saa7191_read_reg(client, SAA7191_REG_HUEC); | |
441 | + reg = saa7191_read_reg(sd, SAA7191_REG_HUEC); | |
436 | 442 | if (reg < 0x80) |
437 | 443 | reg += 0x80; |
438 | 444 | else |
439 | 445 | |
440 | 446 | |
... | ... | @@ -440,18 +446,18 @@ |
440 | 446 | ctrl->value = (s32)reg; |
441 | 447 | break; |
442 | 448 | case SAA7191_CONTROL_VTRC: |
443 | - reg = saa7191_read_reg(client, SAA7191_REG_STDC); | |
449 | + reg = saa7191_read_reg(sd, SAA7191_REG_STDC); | |
444 | 450 | ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0; |
445 | 451 | break; |
446 | 452 | case SAA7191_CONTROL_LUMA_DELAY: |
447 | - reg = saa7191_read_reg(client, SAA7191_REG_CTL3); | |
453 | + reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); | |
448 | 454 | ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK) |
449 | 455 | >> SAA7191_CTL3_YDEL_SHIFT; |
450 | 456 | if (ctrl->value >= 4) |
451 | 457 | ctrl->value -= 8; |
452 | 458 | break; |
453 | 459 | case SAA7191_CONTROL_VNR: |
454 | - reg = saa7191_read_reg(client, SAA7191_REG_CTL4); | |
460 | + reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); | |
455 | 461 | ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK) |
456 | 462 | >> SAA7191_CTL4_VNOI_SHIFT; |
457 | 463 | break; |
... | ... | @@ -462,8 +468,7 @@ |
462 | 468 | return ret; |
463 | 469 | } |
464 | 470 | |
465 | -static int saa7191_set_control(struct i2c_client *client, | |
466 | - struct v4l2_control *ctrl) | |
471 | +static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |
467 | 472 | { |
468 | 473 | u8 reg; |
469 | 474 | int ret = 0; |
... | ... | @@ -472,7 +477,7 @@ |
472 | 477 | case SAA7191_CONTROL_BANDPASS: |
473 | 478 | case SAA7191_CONTROL_BANDPASS_WEIGHT: |
474 | 479 | case SAA7191_CONTROL_CORING: |
475 | - reg = saa7191_read_reg(client, SAA7191_REG_LUMA); | |
480 | + reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); | |
476 | 481 | switch (ctrl->id) { |
477 | 482 | case SAA7191_CONTROL_BANDPASS: |
478 | 483 | reg &= ~SAA7191_LUMA_BPSS_MASK; |
479 | 484 | |
... | ... | @@ -490,11 +495,11 @@ |
490 | 495 | & SAA7191_LUMA_CORI_MASK; |
491 | 496 | break; |
492 | 497 | } |
493 | - ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg); | |
498 | + ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg); | |
494 | 499 | break; |
495 | 500 | case SAA7191_CONTROL_FORCE_COLOUR: |
496 | 501 | case SAA7191_CONTROL_CHROMA_GAIN: |
497 | - reg = saa7191_read_reg(client, SAA7191_REG_GAIN); | |
502 | + reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); | |
498 | 503 | if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) { |
499 | 504 | if (ctrl->value) |
500 | 505 | reg |= SAA7191_GAIN_COLO; |
... | ... | @@ -505,7 +510,7 @@ |
505 | 510 | reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT) |
506 | 511 | & SAA7191_GAIN_LFIS_MASK; |
507 | 512 | } |
508 | - ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg); | |
513 | + ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg); | |
509 | 514 | break; |
510 | 515 | case V4L2_CID_HUE: |
511 | 516 | reg = ctrl->value & 0xff; |
512 | 517 | |
513 | 518 | |
514 | 519 | |
515 | 520 | |
516 | 521 | |
517 | 522 | |
... | ... | @@ -513,33 +518,33 @@ |
513 | 518 | reg += 0x80; |
514 | 519 | else |
515 | 520 | reg -= 0x80; |
516 | - ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg); | |
521 | + ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg); | |
517 | 522 | break; |
518 | 523 | case SAA7191_CONTROL_VTRC: |
519 | - reg = saa7191_read_reg(client, SAA7191_REG_STDC); | |
524 | + reg = saa7191_read_reg(sd, SAA7191_REG_STDC); | |
520 | 525 | if (ctrl->value) |
521 | 526 | reg |= SAA7191_STDC_VTRC; |
522 | 527 | else |
523 | 528 | reg &= ~SAA7191_STDC_VTRC; |
524 | - ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg); | |
529 | + ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg); | |
525 | 530 | break; |
526 | 531 | case SAA7191_CONTROL_LUMA_DELAY: { |
527 | 532 | s32 value = ctrl->value; |
528 | 533 | if (value < 0) |
529 | 534 | value += 8; |
530 | - reg = saa7191_read_reg(client, SAA7191_REG_CTL3); | |
535 | + reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); | |
531 | 536 | reg &= ~SAA7191_CTL3_YDEL_MASK; |
532 | 537 | reg |= (value << SAA7191_CTL3_YDEL_SHIFT) |
533 | 538 | & SAA7191_CTL3_YDEL_MASK; |
534 | - ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg); | |
539 | + ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg); | |
535 | 540 | break; |
536 | 541 | } |
537 | 542 | case SAA7191_CONTROL_VNR: |
538 | - reg = saa7191_read_reg(client, SAA7191_REG_CTL4); | |
543 | + reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); | |
539 | 544 | reg &= ~SAA7191_CTL4_VNOI_MASK; |
540 | 545 | reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT) |
541 | 546 | & SAA7191_CTL4_VNOI_MASK; |
542 | - ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg); | |
547 | + ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg); | |
543 | 548 | break; |
544 | 549 | default: |
545 | 550 | ret = -EINVAL; |
546 | 551 | |
547 | 552 | |
548 | 553 | |
549 | 554 | |
550 | 555 | |
551 | 556 | |
552 | 557 | |
553 | 558 | |
554 | 559 | |
555 | 560 | |
556 | 561 | |
557 | 562 | |
... | ... | @@ -550,57 +555,64 @@ |
550 | 555 | |
551 | 556 | /* I2C-interface */ |
552 | 557 | |
553 | -static int saa7191_command(struct i2c_client *client, unsigned int cmd, | |
554 | - void *arg) | |
558 | +static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status) | |
555 | 559 | { |
556 | - switch (cmd) { | |
557 | - case VIDIOC_INT_G_INPUT_STATUS: { | |
558 | - u32 *iarg = arg; | |
559 | - u8 status; | |
560 | - int res = V4L2_IN_ST_NO_SIGNAL; | |
560 | + u8 status_reg; | |
561 | + int res = V4L2_IN_ST_NO_SIGNAL; | |
561 | 562 | |
562 | - if (saa7191_read_status(client, &status)) | |
563 | - return -EIO; | |
564 | - if ((status & SAA7191_STATUS_HLCK) == 0) | |
565 | - res = 0; | |
566 | - if (!(status & SAA7191_STATUS_CODE)) | |
567 | - res |= V4L2_IN_ST_NO_COLOR; | |
568 | - *iarg = res; | |
569 | - break; | |
570 | - } | |
563 | + if (saa7191_read_status(sd, &status_reg)) | |
564 | + return -EIO; | |
565 | + if ((status_reg & SAA7191_STATUS_HLCK) == 0) | |
566 | + res = 0; | |
567 | + if (!(status_reg & SAA7191_STATUS_CODE)) | |
568 | + res |= V4L2_IN_ST_NO_COLOR; | |
569 | + *status = res; | |
570 | + return 0; | |
571 | +} | |
571 | 572 | |
572 | - case VIDIOC_QUERYSTD: | |
573 | - return saa7191_autodetect_norm_extended(client, arg); | |
574 | 573 | |
575 | - case VIDIOC_S_STD: { | |
576 | - v4l2_std_id *istd = arg; | |
574 | +static int saa7191_g_chip_ident(struct v4l2_subdev *sd, | |
575 | + struct v4l2_dbg_chip_ident *chip) | |
576 | +{ | |
577 | + struct i2c_client *client = v4l2_get_subdevdata(sd); | |
577 | 578 | |
578 | - return saa7191_set_norm(client, *istd); | |
579 | - } | |
580 | - case VIDIOC_INT_S_VIDEO_ROUTING: { | |
581 | - struct v4l2_routing *route = arg; | |
579 | + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0); | |
580 | +} | |
582 | 581 | |
583 | - return saa7191_set_input(client, route->input); | |
584 | - } | |
582 | +static int saa7191_command(struct i2c_client *client, unsigned cmd, void *arg) | |
583 | +{ | |
584 | + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); | |
585 | +} | |
585 | 586 | |
586 | - case VIDIOC_G_CTRL: | |
587 | - return saa7191_get_control(client, arg); | |
587 | +/* ----------------------------------------------------------------------- */ | |
588 | 588 | |
589 | - case VIDIOC_S_CTRL: | |
590 | - return saa7191_set_control(client, arg); | |
589 | +static const struct v4l2_subdev_core_ops saa7191_core_ops = { | |
590 | + .g_chip_ident = saa7191_g_chip_ident, | |
591 | + .g_ctrl = saa7191_g_ctrl, | |
592 | + .s_ctrl = saa7191_s_ctrl, | |
593 | +}; | |
591 | 594 | |
592 | - default: | |
593 | - return -EINVAL; | |
594 | - } | |
595 | +static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = { | |
596 | + .s_std = saa7191_s_std, | |
597 | +}; | |
595 | 598 | |
596 | - return 0; | |
597 | -} | |
599 | +static const struct v4l2_subdev_video_ops saa7191_video_ops = { | |
600 | + .s_routing = saa7191_s_routing, | |
601 | + .querystd = saa7191_querystd, | |
602 | + .g_input_status = saa7191_g_input_status, | |
603 | +}; | |
598 | 604 | |
605 | +static const struct v4l2_subdev_ops saa7191_ops = { | |
606 | + .core = &saa7191_core_ops, | |
607 | + .video = &saa7191_video_ops, | |
608 | +}; | |
609 | + | |
599 | 610 | static int saa7191_probe(struct i2c_client *client, |
600 | 611 | const struct i2c_device_id *id) |
601 | 612 | { |
602 | 613 | int err = 0; |
603 | 614 | struct saa7191 *decoder; |
615 | + struct v4l2_subdev *sd; | |
604 | 616 | |
605 | 617 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
606 | 618 | client->addr << 1, client->adapter->name); |
607 | 619 | |
... | ... | @@ -609,11 +621,10 @@ |
609 | 621 | if (!decoder) |
610 | 622 | return -ENOMEM; |
611 | 623 | |
612 | - i2c_set_clientdata(client, decoder); | |
624 | + sd = &decoder->sd; | |
625 | + v4l2_i2c_subdev_init(sd, client, &saa7191_ops); | |
613 | 626 | |
614 | - decoder->client = client; | |
615 | - | |
616 | - err = saa7191_write_block(client, sizeof(initseq), initseq); | |
627 | + err = saa7191_write_block(sd, sizeof(initseq), initseq); | |
617 | 628 | if (err) { |
618 | 629 | printk(KERN_ERR "SAA7191 initialization failed\n"); |
619 | 630 | kfree(decoder); |
... | ... | @@ -625,7 +636,7 @@ |
625 | 636 | decoder->input = SAA7191_INPUT_COMPOSITE; |
626 | 637 | decoder->norm = V4L2_STD_PAL; |
627 | 638 | |
628 | - err = saa7191_autodetect_norm(client); | |
639 | + err = saa7191_autodetect_norm(sd); | |
629 | 640 | if (err && (err != -EBUSY)) |
630 | 641 | printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); |
631 | 642 | |
632 | 643 | |
... | ... | @@ -634,9 +645,10 @@ |
634 | 645 | |
635 | 646 | static int saa7191_remove(struct i2c_client *client) |
636 | 647 | { |
637 | - struct saa7191 *decoder = i2c_get_clientdata(client); | |
648 | + struct v4l2_subdev *sd = i2c_get_clientdata(client); | |
638 | 649 | |
639 | - kfree(decoder); | |
650 | + v4l2_device_unregister_subdev(sd); | |
651 | + kfree(to_saa7191(sd)); | |
640 | 652 | return 0; |
641 | 653 | } |
642 | 654 |
include/media/v4l2-chip-ident.h