diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa6752hs.c')
-rw-r--r-- | drivers/media/video/saa7134/saa6752hs.c | 440 |
1 files changed, 258 insertions, 182 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 707be175509d..1fb6eccdade3 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -1,3 +1,27 @@ | |||
1 | /* | ||
2 | saa6752hs - i2c-driver for the saa6752hs by Philips | ||
3 | |||
4 | Copyright (C) 2004 Andrew de Quincey | ||
5 | |||
6 | AC-3 support: | ||
7 | |||
8 | Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License vs published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
1 | #include <linux/module.h> | 25 | #include <linux/module.h> |
2 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
3 | #include <linux/string.h> | 27 | #include <linux/string.h> |
@@ -10,6 +34,8 @@ | |||
10 | #include <linux/types.h> | 34 | #include <linux/types.h> |
11 | #include <linux/videodev2.h> | 35 | #include <linux/videodev2.h> |
12 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | #include <media/v4l2-chip-ident.h> | ||
38 | #include <media/v4l2-i2c-drv-legacy.h> | ||
13 | #include <linux/init.h> | 39 | #include <linux/init.h> |
14 | #include <linux/crc32.h> | 40 | #include <linux/crc32.h> |
15 | 41 | ||
@@ -27,9 +53,6 @@ MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); | |||
27 | MODULE_AUTHOR("Andrew de Quincey"); | 53 | MODULE_AUTHOR("Andrew de Quincey"); |
28 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
29 | 55 | ||
30 | static struct i2c_driver driver; | ||
31 | static struct i2c_client client_template; | ||
32 | |||
33 | enum saa6752hs_videoformat { | 56 | enum saa6752hs_videoformat { |
34 | SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ | 57 | SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ |
35 | SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ | 58 | SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ |
@@ -46,7 +69,9 @@ struct saa6752hs_mpeg_params { | |||
46 | __u16 ts_pid_pcr; | 69 | __u16 ts_pid_pcr; |
47 | 70 | ||
48 | /* audio */ | 71 | /* audio */ |
49 | enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; | 72 | enum v4l2_mpeg_audio_encoding au_encoding; |
73 | enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; | ||
74 | enum v4l2_mpeg_audio_ac3_bitrate au_ac3_bitrate; | ||
50 | 75 | ||
51 | /* video */ | 76 | /* video */ |
52 | enum v4l2_mpeg_video_aspect vi_aspect; | 77 | enum v4l2_mpeg_video_aspect vi_aspect; |
@@ -70,7 +95,9 @@ static const struct v4l2_format v4l2_format_table[] = | |||
70 | }; | 95 | }; |
71 | 96 | ||
72 | struct saa6752hs_state { | 97 | struct saa6752hs_state { |
73 | struct i2c_client client; | 98 | int chip; |
99 | u32 revision; | ||
100 | int has_ac3; | ||
74 | struct saa6752hs_mpeg_params params; | 101 | struct saa6752hs_mpeg_params params; |
75 | enum saa6752hs_videoformat video_format; | 102 | enum saa6752hs_videoformat video_format; |
76 | v4l2_std_id standard; | 103 | v4l2_std_id standard; |
@@ -145,6 +172,39 @@ static u8 PMT[] = { | |||
145 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ | 172 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ |
146 | }; | 173 | }; |
147 | 174 | ||
175 | static u8 PMT_AC3[] = { | ||
176 | 0xc2, /* i2c register */ | ||
177 | 0x01, /* table number for encoder(1) */ | ||
178 | 0x47, /* sync */ | ||
179 | |||
180 | 0x40, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0) */ | ||
181 | 0x10, /* PMT PID (0x0010) */ | ||
182 | 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ | ||
183 | |||
184 | 0x00, /* PSI pointer to start of table */ | ||
185 | |||
186 | 0x02, /* TID (2) */ | ||
187 | 0xb0, 0x1a, /* section_syntax_indicator(1), section_length(26) */ | ||
188 | |||
189 | 0x00, 0x01, /* program_number(1) */ | ||
190 | |||
191 | 0xc1, /* version_number(0), current_next_indicator(1) */ | ||
192 | |||
193 | 0x00, 0x00, /* section_number(0), last_section_number(0) */ | ||
194 | |||
195 | 0xe1, 0x04, /* PCR_PID (0x0104) */ | ||
196 | |||
197 | 0xf0, 0x00, /* program_info_length(0) */ | ||
198 | |||
199 | 0x02, 0xe1, 0x00, 0xf0, 0x00, /* video stream type(2), pid */ | ||
200 | 0x06, 0xe1, 0x03, 0xf0, 0x03, /* audio stream type(6), pid */ | ||
201 | 0x6a, /* AC3 */ | ||
202 | 0x01, /* Descriptor_length(1) */ | ||
203 | 0x00, /* component_type_flag(0), bsid_flag(0), mainid_flag(0), asvc_flag(0), reserved flags(0) */ | ||
204 | |||
205 | 0xED, 0xDE, 0x2D, 0xF3 /* CRC32 BE */ | ||
206 | }; | ||
207 | |||
148 | static struct saa6752hs_mpeg_params param_defaults = | 208 | static struct saa6752hs_mpeg_params param_defaults = |
149 | { | 209 | { |
150 | .ts_pid_pmt = 16, | 210 | .ts_pid_pmt = 16, |
@@ -157,12 +217,14 @@ static struct saa6752hs_mpeg_params param_defaults = | |||
157 | .vi_bitrate_peak = 6000, | 217 | .vi_bitrate_peak = 6000, |
158 | .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | 218 | .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, |
159 | 219 | ||
220 | .au_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, | ||
160 | .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, | 221 | .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, |
222 | .au_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_256K, | ||
161 | }; | 223 | }; |
162 | 224 | ||
163 | /* ---------------------------------------------------------------------- */ | 225 | /* ---------------------------------------------------------------------- */ |
164 | 226 | ||
165 | static int saa6752hs_chip_command(struct i2c_client* client, | 227 | static int saa6752hs_chip_command(struct i2c_client *client, |
166 | enum saa6752hs_command command) | 228 | enum saa6752hs_command command) |
167 | { | 229 | { |
168 | unsigned char buf[3]; | 230 | unsigned char buf[3]; |
@@ -229,45 +291,61 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
229 | } | 291 | } |
230 | 292 | ||
231 | 293 | ||
232 | static int saa6752hs_set_bitrate(struct i2c_client* client, | 294 | static inline void set_reg8(struct i2c_client *client, uint8_t reg, uint8_t val) |
233 | struct saa6752hs_mpeg_params* params) | 295 | { |
296 | u8 buf[2]; | ||
297 | |||
298 | buf[0] = reg; | ||
299 | buf[1] = val; | ||
300 | i2c_master_send(client, buf, 2); | ||
301 | } | ||
302 | |||
303 | static inline void set_reg16(struct i2c_client *client, uint8_t reg, uint16_t val) | ||
234 | { | 304 | { |
235 | u8 buf[3]; | 305 | u8 buf[3]; |
306 | |||
307 | buf[0] = reg; | ||
308 | buf[1] = val >> 8; | ||
309 | buf[2] = val & 0xff; | ||
310 | i2c_master_send(client, buf, 3); | ||
311 | } | ||
312 | |||
313 | static int saa6752hs_set_bitrate(struct i2c_client *client, | ||
314 | struct saa6752hs_state *h) | ||
315 | { | ||
316 | struct saa6752hs_mpeg_params *params = &h->params; | ||
236 | int tot_bitrate; | 317 | int tot_bitrate; |
318 | int is_384k; | ||
237 | 319 | ||
238 | /* set the bitrate mode */ | 320 | /* set the bitrate mode */ |
239 | buf[0] = 0x71; | 321 | set_reg8(client, 0x71, |
240 | buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; | 322 | params->vi_bitrate_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); |
241 | i2c_master_send(client, buf, 2); | ||
242 | 323 | ||
243 | /* set the video bitrate */ | 324 | /* set the video bitrate */ |
244 | if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { | 325 | if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { |
245 | /* set the target bitrate */ | 326 | /* set the target bitrate */ |
246 | buf[0] = 0x80; | 327 | set_reg16(client, 0x80, params->vi_bitrate); |
247 | buf[1] = params->vi_bitrate >> 8; | ||
248 | buf[2] = params->vi_bitrate & 0xff; | ||
249 | i2c_master_send(client, buf, 3); | ||
250 | 328 | ||
251 | /* set the max bitrate */ | 329 | /* set the max bitrate */ |
252 | buf[0] = 0x81; | 330 | set_reg16(client, 0x81, params->vi_bitrate_peak); |
253 | buf[1] = params->vi_bitrate_peak >> 8; | ||
254 | buf[2] = params->vi_bitrate_peak & 0xff; | ||
255 | i2c_master_send(client, buf, 3); | ||
256 | tot_bitrate = params->vi_bitrate_peak; | 331 | tot_bitrate = params->vi_bitrate_peak; |
257 | } else { | 332 | } else { |
258 | /* set the target bitrate (no max bitrate for CBR) */ | 333 | /* set the target bitrate (no max bitrate for CBR) */ |
259 | buf[0] = 0x81; | 334 | set_reg16(client, 0x81, params->vi_bitrate); |
260 | buf[1] = params->vi_bitrate >> 8; | ||
261 | buf[2] = params->vi_bitrate & 0xff; | ||
262 | i2c_master_send(client, buf, 3); | ||
263 | tot_bitrate = params->vi_bitrate; | 335 | tot_bitrate = params->vi_bitrate; |
264 | } | 336 | } |
265 | 337 | ||
338 | /* set the audio encoding */ | ||
339 | set_reg8(client, 0x93, | ||
340 | params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); | ||
341 | |||
266 | /* set the audio bitrate */ | 342 | /* set the audio bitrate */ |
267 | buf[0] = 0x94; | 343 | if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) |
268 | buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; | 344 | is_384k = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; |
269 | i2c_master_send(client, buf, 2); | 345 | else |
270 | tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384; | 346 | is_384k = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; |
347 | set_reg8(client, 0x94, is_384k); | ||
348 | tot_bitrate += is_384k ? 384 : 256; | ||
271 | 349 | ||
272 | /* Note: the total max bitrate is determined by adding the video and audio | 350 | /* Note: the total max bitrate is determined by adding the video and audio |
273 | bitrates together and also adding an extra 768kbit/s to stay on the | 351 | bitrates together and also adding an extra 768kbit/s to stay on the |
@@ -278,16 +356,12 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, | |||
278 | tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; | 356 | tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; |
279 | 357 | ||
280 | /* set the total bitrate */ | 358 | /* set the total bitrate */ |
281 | buf[0] = 0xb1; | 359 | set_reg16(client, 0xb1, tot_bitrate); |
282 | buf[1] = tot_bitrate >> 8; | ||
283 | buf[2] = tot_bitrate & 0xff; | ||
284 | i2c_master_send(client, buf, 3); | ||
285 | |||
286 | return 0; | 360 | return 0; |
287 | } | 361 | } |
288 | 362 | ||
289 | static void saa6752hs_set_subsampling(struct i2c_client* client, | 363 | static void saa6752hs_set_subsampling(struct i2c_client *client, |
290 | struct v4l2_format* f) | 364 | struct v4l2_format *f) |
291 | { | 365 | { |
292 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 366 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
293 | int dist_352, dist_480, dist_720; | 367 | int dist_352, dist_480, dist_720; |
@@ -332,7 +406,7 @@ static void saa6752hs_set_subsampling(struct i2c_client* client, | |||
332 | } | 406 | } |
333 | 407 | ||
334 | 408 | ||
335 | static int handle_ctrl(struct saa6752hs_mpeg_params *params, | 409 | static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, |
336 | struct v4l2_ext_control *ctrl, unsigned int cmd) | 410 | struct v4l2_ext_control *ctrl, unsigned int cmd) |
337 | { | 411 | { |
338 | int old = 0, new; | 412 | int old = 0, new; |
@@ -379,8 +453,9 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, | |||
379 | params->ts_pid_pcr = new; | 453 | params->ts_pid_pcr = new; |
380 | break; | 454 | break; |
381 | case V4L2_CID_MPEG_AUDIO_ENCODING: | 455 | case V4L2_CID_MPEG_AUDIO_ENCODING: |
382 | old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; | 456 | old = params->au_encoding; |
383 | if (set && new != old) | 457 | if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && |
458 | (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) | ||
384 | return -ERANGE; | 459 | return -ERANGE; |
385 | new = old; | 460 | new = old; |
386 | break; | 461 | break; |
@@ -395,6 +470,19 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, | |||
395 | new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | 470 | new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; |
396 | params->au_l2_bitrate = new; | 471 | params->au_l2_bitrate = new; |
397 | break; | 472 | break; |
473 | case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: | ||
474 | if (!has_ac3) | ||
475 | return -EINVAL; | ||
476 | old = params->au_ac3_bitrate; | ||
477 | if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K && | ||
478 | new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K) | ||
479 | return -ERANGE; | ||
480 | if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K) | ||
481 | new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K; | ||
482 | else | ||
483 | new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K; | ||
484 | params->au_ac3_bitrate = new; | ||
485 | break; | ||
398 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | 486 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: |
399 | old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; | 487 | old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; |
400 | if (set && new != old) | 488 | if (set && new != old) |
@@ -448,17 +536,19 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, | |||
448 | return 0; | 536 | return 0; |
449 | } | 537 | } |
450 | 538 | ||
451 | static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, | 539 | static int saa6752hs_qctrl(struct saa6752hs_state *h, |
452 | struct v4l2_queryctrl *qctrl) | 540 | struct v4l2_queryctrl *qctrl) |
453 | { | 541 | { |
542 | struct saa6752hs_mpeg_params *params = &h->params; | ||
454 | int err; | 543 | int err; |
455 | 544 | ||
456 | switch (qctrl->id) { | 545 | switch (qctrl->id) { |
457 | case V4L2_CID_MPEG_AUDIO_ENCODING: | 546 | case V4L2_CID_MPEG_AUDIO_ENCODING: |
458 | return v4l2_ctrl_query_fill(qctrl, | 547 | return v4l2_ctrl_query_fill(qctrl, |
459 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, | 548 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, |
460 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, | 549 | h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : |
461 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2); | 550 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, |
551 | 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); | ||
462 | 552 | ||
463 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | 553 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: |
464 | return v4l2_ctrl_query_fill(qctrl, | 554 | return v4l2_ctrl_query_fill(qctrl, |
@@ -466,6 +556,14 @@ static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, | |||
466 | V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, | 556 | V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, |
467 | V4L2_MPEG_AUDIO_L2_BITRATE_256K); | 557 | V4L2_MPEG_AUDIO_L2_BITRATE_256K); |
468 | 558 | ||
559 | case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: | ||
560 | if (!h->has_ac3) | ||
561 | return -EINVAL; | ||
562 | return v4l2_ctrl_query_fill(qctrl, | ||
563 | V4L2_MPEG_AUDIO_AC3_BITRATE_256K, | ||
564 | V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1, | ||
565 | V4L2_MPEG_AUDIO_AC3_BITRATE_256K); | ||
566 | |||
469 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | 567 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: |
470 | return v4l2_ctrl_query_fill(qctrl, | 568 | return v4l2_ctrl_query_fill(qctrl, |
471 | V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, | 569 | V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, |
@@ -512,44 +610,57 @@ static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, | |||
512 | return -EINVAL; | 610 | return -EINVAL; |
513 | } | 611 | } |
514 | 612 | ||
515 | static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params, | 613 | static int saa6752hs_qmenu(struct saa6752hs_state *h, |
516 | struct v4l2_querymenu *qmenu) | 614 | struct v4l2_querymenu *qmenu) |
517 | { | 615 | { |
518 | static const char *mpeg_audio_l2_bitrate[] = { | 616 | static const u32 mpeg_audio_encoding[] = { |
519 | "", | 617 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, |
520 | "", | 618 | V4L2_CTRL_MENU_IDS_END |
521 | "", | 619 | }; |
522 | "", | 620 | static const u32 mpeg_audio_ac3_encoding[] = { |
523 | "", | 621 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, |
524 | "", | 622 | V4L2_MPEG_AUDIO_ENCODING_AC3, |
525 | "", | 623 | V4L2_CTRL_MENU_IDS_END |
526 | "", | 624 | }; |
527 | "", | 625 | static u32 mpeg_audio_l2_bitrate[] = { |
528 | "", | 626 | V4L2_MPEG_AUDIO_L2_BITRATE_256K, |
529 | "", | 627 | V4L2_MPEG_AUDIO_L2_BITRATE_384K, |
530 | "256 kbps", | 628 | V4L2_CTRL_MENU_IDS_END |
531 | "", | 629 | }; |
532 | "384 kbps", | 630 | static u32 mpeg_audio_ac3_bitrate[] = { |
533 | NULL | 631 | V4L2_MPEG_AUDIO_AC3_BITRATE_256K, |
632 | V4L2_MPEG_AUDIO_AC3_BITRATE_384K, | ||
633 | V4L2_CTRL_MENU_IDS_END | ||
534 | }; | 634 | }; |
535 | struct v4l2_queryctrl qctrl; | 635 | struct v4l2_queryctrl qctrl; |
536 | int err; | 636 | int err; |
537 | 637 | ||
538 | qctrl.id = qmenu->id; | 638 | qctrl.id = qmenu->id; |
539 | err = saa6752hs_qctrl(params, &qctrl); | 639 | err = saa6752hs_qctrl(h, &qctrl); |
540 | if (err) | 640 | if (err) |
541 | return err; | 641 | return err; |
542 | if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE) | 642 | switch (qmenu->id) { |
543 | return v4l2_ctrl_query_menu(qmenu, &qctrl, | 643 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: |
644 | return v4l2_ctrl_query_menu_valid_items(qmenu, | ||
544 | mpeg_audio_l2_bitrate); | 645 | mpeg_audio_l2_bitrate); |
545 | return v4l2_ctrl_query_menu(qmenu, &qctrl, | 646 | case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: |
546 | v4l2_ctrl_get_menu(qmenu->id)); | 647 | if (!h->has_ac3) |
648 | return -EINVAL; | ||
649 | return v4l2_ctrl_query_menu_valid_items(qmenu, | ||
650 | mpeg_audio_ac3_bitrate); | ||
651 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
652 | return v4l2_ctrl_query_menu_valid_items(qmenu, | ||
653 | h->has_ac3 ? mpeg_audio_ac3_encoding : | ||
654 | mpeg_audio_encoding); | ||
655 | } | ||
656 | return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); | ||
547 | } | 657 | } |
548 | 658 | ||
549 | static int saa6752hs_init(struct i2c_client* client) | 659 | static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) |
550 | { | 660 | { |
551 | unsigned char buf[9], buf2[4]; | 661 | unsigned char buf[9], buf2[4]; |
552 | struct saa6752hs_state *h; | 662 | struct saa6752hs_state *h; |
663 | unsigned size; | ||
553 | u32 crc; | 664 | u32 crc; |
554 | unsigned char localPAT[256]; | 665 | unsigned char localPAT[256]; |
555 | unsigned char localPMT[256]; | 666 | unsigned char localPMT[256]; |
@@ -557,45 +668,31 @@ static int saa6752hs_init(struct i2c_client* client) | |||
557 | h = i2c_get_clientdata(client); | 668 | h = i2c_get_clientdata(client); |
558 | 669 | ||
559 | /* Set video format - must be done first as it resets other settings */ | 670 | /* Set video format - must be done first as it resets other settings */ |
560 | buf[0] = 0x41; | 671 | set_reg8(client, 0x41, h->video_format); |
561 | buf[1] = h->video_format; | ||
562 | i2c_master_send(client, buf, 2); | ||
563 | 672 | ||
564 | /* Set number of lines in input signal */ | 673 | /* Set number of lines in input signal */ |
565 | buf[0] = 0x40; | 674 | set_reg8(client, 0x40, (h->standard & V4L2_STD_525_60) ? 1 : 0); |
566 | buf[1] = 0x00; | ||
567 | if (h->standard & V4L2_STD_525_60) | ||
568 | buf[1] = 0x01; | ||
569 | i2c_master_send(client, buf, 2); | ||
570 | 675 | ||
571 | /* set bitrate */ | 676 | /* set bitrate */ |
572 | saa6752hs_set_bitrate(client, &h->params); | 677 | saa6752hs_set_bitrate(client, h); |
573 | 678 | ||
574 | /* Set GOP structure {3, 13} */ | 679 | /* Set GOP structure {3, 13} */ |
575 | buf[0] = 0x72; | 680 | set_reg16(client, 0x72, 0x030d); |
576 | buf[1] = 0x03; | ||
577 | buf[2] = 0x0D; | ||
578 | i2c_master_send(client,buf,3); | ||
579 | 681 | ||
580 | /* Set minimum Q-scale {4} */ | 682 | /* Set minimum Q-scale {4} */ |
581 | buf[0] = 0x82; | 683 | set_reg8(client, 0x82, 0x04); |
582 | buf[1] = 0x04; | ||
583 | i2c_master_send(client,buf,2); | ||
584 | 684 | ||
585 | /* Set maximum Q-scale {12} */ | 685 | /* Set maximum Q-scale {12} */ |
586 | buf[0] = 0x83; | 686 | set_reg8(client, 0x83, 0x0c); |
587 | buf[1] = 0x0C; | ||
588 | i2c_master_send(client,buf,2); | ||
589 | 687 | ||
590 | /* Set Output Protocol */ | 688 | /* Set Output Protocol */ |
591 | buf[0] = 0xD0; | 689 | set_reg8(client, 0xd0, 0x81); |
592 | buf[1] = 0x81; | ||
593 | i2c_master_send(client,buf,2); | ||
594 | 690 | ||
595 | /* Set video output stream format {TS} */ | 691 | /* Set video output stream format {TS} */ |
596 | buf[0] = 0xB0; | 692 | set_reg8(client, 0xb0, 0x05); |
597 | buf[1] = 0x05; | 693 | |
598 | i2c_master_send(client,buf,2); | 694 | /* Set leading null byte for TS */ |
695 | set_reg16(client, 0xf6, leading_null_bytes); | ||
599 | 696 | ||
600 | /* compute PAT */ | 697 | /* compute PAT */ |
601 | memcpy(localPAT, PAT, sizeof(PAT)); | 698 | memcpy(localPAT, PAT, sizeof(PAT)); |
@@ -608,7 +705,13 @@ static int saa6752hs_init(struct i2c_client* client) | |||
608 | localPAT[sizeof(PAT) - 1] = crc & 0xFF; | 705 | localPAT[sizeof(PAT) - 1] = crc & 0xFF; |
609 | 706 | ||
610 | /* compute PMT */ | 707 | /* compute PMT */ |
611 | memcpy(localPMT, PMT, sizeof(PMT)); | 708 | if (h->params.au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) { |
709 | size = sizeof(PMT_AC3); | ||
710 | memcpy(localPMT, PMT_AC3, size); | ||
711 | } else { | ||
712 | size = sizeof(PMT); | ||
713 | memcpy(localPMT, PMT, size); | ||
714 | } | ||
612 | localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); | 715 | localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); |
613 | localPMT[4] = h->params.ts_pid_pmt & 0xff; | 716 | localPMT[4] = h->params.ts_pid_pmt & 0xff; |
614 | localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); | 717 | localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); |
@@ -617,40 +720,28 @@ static int saa6752hs_init(struct i2c_client* client) | |||
617 | localPMT[21] = h->params.ts_pid_video & 0xFF; | 720 | localPMT[21] = h->params.ts_pid_video & 0xFF; |
618 | localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F); | 721 | localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F); |
619 | localPMT[26] = h->params.ts_pid_audio & 0xFF; | 722 | localPMT[26] = h->params.ts_pid_audio & 0xFF; |
620 | crc = crc32_be(~0, &localPMT[7], sizeof(PMT) - 7 - 4); | 723 | crc = crc32_be(~0, &localPMT[7], size - 7 - 4); |
621 | localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF; | 724 | localPMT[size - 4] = (crc >> 24) & 0xFF; |
622 | localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF; | 725 | localPMT[size - 3] = (crc >> 16) & 0xFF; |
623 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; | 726 | localPMT[size - 2] = (crc >> 8) & 0xFF; |
624 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; | 727 | localPMT[size - 1] = crc & 0xFF; |
625 | 728 | ||
626 | /* Set Audio PID */ | 729 | /* Set Audio PID */ |
627 | buf[0] = 0xC1; | 730 | set_reg16(client, 0xc1, h->params.ts_pid_audio); |
628 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; | ||
629 | buf[2] = h->params.ts_pid_audio & 0xFF; | ||
630 | i2c_master_send(client,buf,3); | ||
631 | 731 | ||
632 | /* Set Video PID */ | 732 | /* Set Video PID */ |
633 | buf[0] = 0xC0; | 733 | set_reg16(client, 0xc0, h->params.ts_pid_video); |
634 | buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; | ||
635 | buf[2] = h->params.ts_pid_video & 0xFF; | ||
636 | i2c_master_send(client,buf,3); | ||
637 | 734 | ||
638 | /* Set PCR PID */ | 735 | /* Set PCR PID */ |
639 | buf[0] = 0xC4; | 736 | set_reg16(client, 0xc4, h->params.ts_pid_pcr); |
640 | buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; | ||
641 | buf[2] = h->params.ts_pid_pcr & 0xFF; | ||
642 | i2c_master_send(client,buf,3); | ||
643 | 737 | ||
644 | /* Send SI tables */ | 738 | /* Send SI tables */ |
645 | i2c_master_send(client,localPAT,sizeof(PAT)); | 739 | i2c_master_send(client, localPAT, sizeof(PAT)); |
646 | i2c_master_send(client,localPMT,sizeof(PMT)); | 740 | i2c_master_send(client, localPMT, size); |
647 | 741 | ||
648 | /* mute then unmute audio. This removes buzzing artefacts */ | 742 | /* mute then unmute audio. This removes buzzing artefacts */ |
649 | buf[0] = 0xa4; | 743 | set_reg8(client, 0xa4, 1); |
650 | buf[1] = 1; | 744 | set_reg8(client, 0xa4, 0); |
651 | i2c_master_send(client, buf, 2); | ||
652 | buf[1] = 0; | ||
653 | i2c_master_send(client, buf, 2); | ||
654 | 745 | ||
655 | /* start it going */ | 746 | /* start it going */ |
656 | saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); | 747 | saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); |
@@ -688,45 +779,6 @@ static int saa6752hs_init(struct i2c_client* client) | |||
688 | return 0; | 779 | return 0; |
689 | } | 780 | } |
690 | 781 | ||
691 | static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | ||
692 | { | ||
693 | struct saa6752hs_state *h; | ||
694 | |||
695 | |||
696 | if (NULL == (h = kzalloc(sizeof(*h), GFP_KERNEL))) | ||
697 | return -ENOMEM; | ||
698 | h->client = client_template; | ||
699 | h->params = param_defaults; | ||
700 | h->client.adapter = adap; | ||
701 | h->client.addr = addr; | ||
702 | |||
703 | /* Assume 625 input lines */ | ||
704 | h->standard = 0; | ||
705 | |||
706 | i2c_set_clientdata(&h->client, h); | ||
707 | i2c_attach_client(&h->client); | ||
708 | |||
709 | v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int saa6752hs_probe(struct i2c_adapter *adap) | ||
714 | { | ||
715 | if (adap->class & I2C_CLASS_TV_ANALOG) | ||
716 | return i2c_probe(adap, &addr_data, saa6752hs_attach); | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int saa6752hs_detach(struct i2c_client *client) | ||
721 | { | ||
722 | struct saa6752hs_state *h; | ||
723 | |||
724 | h = i2c_get_clientdata(client); | ||
725 | i2c_detach_client(client); | ||
726 | kfree(h); | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static int | 782 | static int |
731 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | 783 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) |
732 | { | 784 | { |
@@ -737,14 +789,13 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
737 | int i; | 789 | int i; |
738 | 790 | ||
739 | switch (cmd) { | 791 | switch (cmd) { |
792 | case VIDIOC_INT_INIT: | ||
793 | /* apply settings and start encoder */ | ||
794 | saa6752hs_init(client, *(u32 *)arg); | ||
795 | break; | ||
740 | case VIDIOC_S_EXT_CTRLS: | 796 | case VIDIOC_S_EXT_CTRLS: |
741 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | 797 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) |
742 | return -EINVAL; | 798 | return -EINVAL; |
743 | if (ctrls->count == 0) { | ||
744 | /* apply settings and start encoder */ | ||
745 | saa6752hs_init(client); | ||
746 | break; | ||
747 | } | ||
748 | /* fall through */ | 799 | /* fall through */ |
749 | case VIDIOC_TRY_EXT_CTRLS: | 800 | case VIDIOC_TRY_EXT_CTRLS: |
750 | case VIDIOC_G_EXT_CTRLS: | 801 | case VIDIOC_G_EXT_CTRLS: |
@@ -752,7 +803,8 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
752 | return -EINVAL; | 803 | return -EINVAL; |
753 | params = h->params; | 804 | params = h->params; |
754 | for (i = 0; i < ctrls->count; i++) { | 805 | for (i = 0; i < ctrls->count; i++) { |
755 | if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { | 806 | err = handle_ctrl(h->has_ac3, ¶ms, ctrls->controls + i, cmd); |
807 | if (err) { | ||
756 | ctrls->error_idx = i; | 808 | ctrls->error_idx = i; |
757 | return err; | 809 | return err; |
758 | } | 810 | } |
@@ -760,9 +812,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
760 | h->params = params; | 812 | h->params = params; |
761 | break; | 813 | break; |
762 | case VIDIOC_QUERYCTRL: | 814 | case VIDIOC_QUERYCTRL: |
763 | return saa6752hs_qctrl(&h->params, arg); | 815 | return saa6752hs_qctrl(h, arg); |
764 | case VIDIOC_QUERYMENU: | 816 | case VIDIOC_QUERYMENU: |
765 | return saa6752hs_qmenu(&h->params, arg); | 817 | return saa6752hs_qmenu(h, arg); |
766 | case VIDIOC_G_FMT: | 818 | case VIDIOC_G_FMT: |
767 | { | 819 | { |
768 | struct v4l2_format *f = arg; | 820 | struct v4l2_format *f = arg; |
@@ -785,6 +837,11 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
785 | case VIDIOC_S_STD: | 837 | case VIDIOC_S_STD: |
786 | h->standard = *((v4l2_std_id *) arg); | 838 | h->standard = *((v4l2_std_id *) arg); |
787 | break; | 839 | break; |
840 | |||
841 | case VIDIOC_G_CHIP_IDENT: | ||
842 | return v4l2_chip_ident_i2c_client(client, | ||
843 | arg, h->chip, h->revision); | ||
844 | |||
788 | default: | 845 | default: |
789 | /* nothing */ | 846 | /* nothing */ |
790 | break; | 847 | break; |
@@ -793,36 +850,55 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
793 | return err; | 850 | return err; |
794 | } | 851 | } |
795 | 852 | ||
796 | /* ----------------------------------------------------------------------- */ | 853 | static int saa6752hs_probe(struct i2c_client *client, |
854 | const struct i2c_device_id *id) | ||
855 | { | ||
856 | struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
857 | u8 addr = 0x13; | ||
858 | u8 data[12]; | ||
797 | 859 | ||
798 | static struct i2c_driver driver = { | 860 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
799 | .driver = { | 861 | client->addr << 1, client->adapter->name); |
800 | .name = "saa6752hs", | 862 | if (h == NULL) |
801 | }, | 863 | return -ENOMEM; |
802 | .id = I2C_DRIVERID_SAA6752HS, | ||
803 | .attach_adapter = saa6752hs_probe, | ||
804 | .detach_client = saa6752hs_detach, | ||
805 | .command = saa6752hs_command, | ||
806 | }; | ||
807 | 864 | ||
808 | static struct i2c_client client_template = | 865 | i2c_master_send(client, &addr, 1); |
809 | { | 866 | i2c_master_recv(client, data, sizeof(data)); |
810 | .name = "saa6752hs", | 867 | h->chip = V4L2_IDENT_SAA6752HS; |
811 | .driver = &driver, | 868 | h->revision = (data[8] << 8) | data[9]; |
812 | }; | 869 | h->has_ac3 = 0; |
870 | if (h->revision == 0x0206) { | ||
871 | h->chip = V4L2_IDENT_SAA6752HS_AC3; | ||
872 | h->has_ac3 = 1; | ||
873 | v4l_info(client, "support AC-3\n"); | ||
874 | } | ||
875 | h->params = param_defaults; | ||
876 | h->standard = 0; /* Assume 625 input lines */ | ||
813 | 877 | ||
814 | static int __init saa6752hs_init_module(void) | 878 | i2c_set_clientdata(client, h); |
815 | { | 879 | return 0; |
816 | return i2c_add_driver(&driver); | ||
817 | } | 880 | } |
818 | 881 | ||
819 | static void __exit saa6752hs_cleanup_module(void) | 882 | static int saa6752hs_remove(struct i2c_client *client) |
820 | { | 883 | { |
821 | i2c_del_driver(&driver); | 884 | kfree(i2c_get_clientdata(client)); |
885 | return 0; | ||
822 | } | 886 | } |
823 | 887 | ||
824 | module_init(saa6752hs_init_module); | 888 | static const struct i2c_device_id saa6752hs_id[] = { |
825 | module_exit(saa6752hs_cleanup_module); | 889 | { "saa6752hs", 0 }, |
890 | { } | ||
891 | }; | ||
892 | MODULE_DEVICE_TABLE(i2c, saa6752hs_id); | ||
893 | |||
894 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
895 | .name = "saa6752hs", | ||
896 | .driverid = I2C_DRIVERID_SAA6752HS, | ||
897 | .command = saa6752hs_command, | ||
898 | .probe = saa6752hs_probe, | ||
899 | .remove = saa6752hs_remove, | ||
900 | .id_table = saa6752hs_id, | ||
901 | }; | ||
826 | 902 | ||
827 | /* | 903 | /* |
828 | * Overrides for Emacs so that we follow Linus's tabbing style. | 904 | * Overrides for Emacs so that we follow Linus's tabbing style. |