diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 16:03:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 16:03:58 -0500 |
commit | f17578decc40df8fceff82b106582e30bdfb3189 (patch) | |
tree | 911a435a2094ac03ae649f020237674224e4124a /drivers | |
parent | 682e852e2638ed0aff84aa51181c9e5d2f939562 (diff) | |
parent | cec418346e5a411e907293aba7cc21ac53c95834 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
Diffstat (limited to 'drivers')
186 files changed, 10519 insertions, 4784 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 09ec964dec5c..b614612be7b4 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -253,7 +253,10 @@ static int fops_open(struct inode *inode, struct file *file) | |||
253 | 253 | ||
254 | if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 254 | if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
255 | DEB_S(("initializing vbi...\n")); | 255 | DEB_S(("initializing vbi...\n")); |
256 | result = saa7146_vbi_uops.open(dev,file); | 256 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) |
257 | result = saa7146_vbi_uops.open(dev,file); | ||
258 | if (dev->ext_vv_data->vbi_fops.open) | ||
259 | dev->ext_vv_data->vbi_fops.open(inode, file); | ||
257 | } else { | 260 | } else { |
258 | DEB_S(("initializing video...\n")); | 261 | DEB_S(("initializing video...\n")); |
259 | result = saa7146_video_uops.open(dev,file); | 262 | result = saa7146_video_uops.open(dev,file); |
@@ -289,7 +292,10 @@ static int fops_release(struct inode *inode, struct file *file) | |||
289 | return -ERESTARTSYS; | 292 | return -ERESTARTSYS; |
290 | 293 | ||
291 | if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 294 | if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
292 | saa7146_vbi_uops.release(dev,file); | 295 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) |
296 | saa7146_vbi_uops.release(dev,file); | ||
297 | if (dev->ext_vv_data->vbi_fops.release) | ||
298 | dev->ext_vv_data->vbi_fops.release(inode, file); | ||
293 | } else { | 299 | } else { |
294 | saa7146_video_uops.release(dev,file); | 300 | saa7146_video_uops.release(dev,file); |
295 | } | 301 | } |
@@ -332,6 +338,7 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma) | |||
332 | BUG(); | 338 | BUG(); |
333 | return 0; | 339 | return 0; |
334 | } | 340 | } |
341 | |||
335 | return videobuf_mmap_mapper(q,vma); | 342 | return videobuf_mmap_mapper(q,vma); |
336 | } | 343 | } |
337 | 344 | ||
@@ -381,7 +388,10 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof | |||
381 | } | 388 | } |
382 | case V4L2_BUF_TYPE_VBI_CAPTURE: { | 389 | case V4L2_BUF_TYPE_VBI_CAPTURE: { |
383 | // DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); | 390 | // DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); |
384 | return saa7146_vbi_uops.read(file,data,count,ppos); | 391 | if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) |
392 | return saa7146_vbi_uops.read(file,data,count,ppos); | ||
393 | else | ||
394 | return -EINVAL; | ||
385 | } | 395 | } |
386 | break; | 396 | break; |
387 | default: | 397 | default: |
@@ -390,12 +400,31 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof | |||
390 | } | 400 | } |
391 | } | 401 | } |
392 | 402 | ||
403 | static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) | ||
404 | { | ||
405 | struct saa7146_fh *fh = file->private_data; | ||
406 | |||
407 | switch (fh->type) { | ||
408 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
409 | return -EINVAL; | ||
410 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
411 | if (fh->dev->ext_vv_data->vbi_fops.write) | ||
412 | return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); | ||
413 | else | ||
414 | return -EINVAL; | ||
415 | default: | ||
416 | BUG(); | ||
417 | return -EINVAL; | ||
418 | } | ||
419 | } | ||
420 | |||
393 | static struct file_operations video_fops = | 421 | static struct file_operations video_fops = |
394 | { | 422 | { |
395 | .owner = THIS_MODULE, | 423 | .owner = THIS_MODULE, |
396 | .open = fops_open, | 424 | .open = fops_open, |
397 | .release = fops_release, | 425 | .release = fops_release, |
398 | .read = fops_read, | 426 | .read = fops_read, |
427 | .write = fops_write, | ||
399 | .poll = fops_poll, | 428 | .poll = fops_poll, |
400 | .mmap = fops_mmap, | 429 | .mmap = fops_mmap, |
401 | .ioctl = fops_ioctl, | 430 | .ioctl = fops_ioctl, |
@@ -467,7 +496,8 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) | |||
467 | memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); | 496 | memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); |
468 | 497 | ||
469 | saa7146_video_uops.init(dev,vv); | 498 | saa7146_video_uops.init(dev,vv); |
470 | saa7146_vbi_uops.init(dev,vv); | 499 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) |
500 | saa7146_vbi_uops.init(dev,vv); | ||
471 | 501 | ||
472 | dev->vv_data = vv; | 502 | dev->vv_data = vv; |
473 | dev->vv_callback = &vv_callback; | 503 | dev->vv_callback = &vv_callback; |
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c index ec52dff8cb69..33bec8a6843b 100644 --- a/drivers/media/common/saa7146_hlp.c +++ b/drivers/media/common/saa7146_hlp.c | |||
@@ -562,19 +562,26 @@ static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int | |||
562 | 562 | ||
563 | int b_depth = vv->ov_fmt->depth; | 563 | int b_depth = vv->ov_fmt->depth; |
564 | int b_bpl = vv->ov_fb.fmt.bytesperline; | 564 | int b_bpl = vv->ov_fb.fmt.bytesperline; |
565 | u32 base = (u32)vv->ov_fb.base; | 565 | /* The unsigned long cast is to remove a 64-bit compile warning since |
566 | it looks like a 64-bit address is cast to a 32-bit value, even | ||
567 | though the base pointer is really a 32-bit physical address that | ||
568 | goes into a 32-bit DMA register. | ||
569 | FIXME: might not work on some 64-bit platforms, but see the FIXME | ||
570 | in struct v4l2_framebuffer (videodev2.h) for that. | ||
571 | */ | ||
572 | u32 base = (u32)(unsigned long)vv->ov_fb.base; | ||
566 | 573 | ||
567 | struct saa7146_video_dma vdma1; | 574 | struct saa7146_video_dma vdma1; |
568 | 575 | ||
569 | /* calculate memory offsets for picture, look if we shall top-down-flip */ | 576 | /* calculate memory offsets for picture, look if we shall top-down-flip */ |
570 | vdma1.pitch = 2*b_bpl; | 577 | vdma1.pitch = 2*b_bpl; |
571 | if ( 0 == vv->vflip ) { | 578 | if ( 0 == vv->vflip ) { |
572 | vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); | 579 | vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); |
573 | vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); | 580 | vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); |
574 | vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2)); | 581 | vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2)); |
575 | } | 582 | } |
576 | else { | 583 | else { |
577 | vdma1.base_even = (u32)base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); | 584 | vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); |
578 | vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2); | 585 | vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2); |
579 | vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2)); | 586 | vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2)); |
580 | } | 587 | } |
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index 063986ec16b5..468d3c959075 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c | |||
@@ -500,9 +500,9 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff | |||
500 | } | 500 | } |
501 | 501 | ||
502 | struct saa7146_use_ops saa7146_vbi_uops = { | 502 | struct saa7146_use_ops saa7146_vbi_uops = { |
503 | .init = vbi_init, | 503 | .init = vbi_init, |
504 | .open = vbi_open, | 504 | .open = vbi_open, |
505 | .release = vbi_close, | 505 | .release = vbi_close, |
506 | .irq_done = vbi_irq_done, | 506 | .irq_done = vbi_irq_done, |
507 | .read = vbi_read, | 507 | .read = vbi_read, |
508 | }; | 508 | }; |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 1d961023b837..7ebac7949df3 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -151,8 +151,8 @@ static int try_win(struct saa7146_dev *dev, struct v4l2_window *win) | |||
151 | 151 | ||
152 | if (V4L2_FIELD_ANY == field) { | 152 | if (V4L2_FIELD_ANY == field) { |
153 | field = (win->w.height > maxh/2) | 153 | field = (win->w.height > maxh/2) |
154 | ? V4L2_FIELD_INTERLACED | 154 | ? V4L2_FIELD_INTERLACED |
155 | : V4L2_FIELD_TOP; | 155 | : V4L2_FIELD_TOP; |
156 | } | 156 | } |
157 | switch (field) { | 157 | switch (field) { |
158 | case V4L2_FIELD_TOP: | 158 | case V4L2_FIELD_TOP: |
@@ -1114,10 +1114,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
1114 | return 0; | 1114 | return 0; |
1115 | } | 1115 | } |
1116 | case VIDIOC_OVERLAY: | 1116 | case VIDIOC_OVERLAY: |
1117 | |||
1118 | |||
1119 | |||
1120 | |||
1121 | { | 1117 | { |
1122 | int on = *(int *)arg; | 1118 | int on = *(int *)arg; |
1123 | int err = 0; | 1119 | int err = 0; |
@@ -1359,7 +1355,6 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
1359 | saa7146_buffer_queue(fh->dev,&vv->video_q,buf); | 1355 | saa7146_buffer_queue(fh->dev,&vv->video_q,buf); |
1360 | } | 1356 | } |
1361 | 1357 | ||
1362 | |||
1363 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 1358 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) |
1364 | { | 1359 | { |
1365 | struct file *file = q->priv_data; | 1360 | struct file *file = q->priv_data; |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 21a9045b3ef6..0b940e152b79 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -298,7 +298,7 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir | |||
298 | } | 298 | } |
299 | 299 | ||
300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, | 300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, |
301 | struct dvb_frontend_parameters* params) | 301 | struct dvb_frontend_parameters* params) |
302 | { | 302 | { |
303 | struct flexcop_device *fc = fe->dvb->priv; | 303 | struct flexcop_device *fc = fe->dvb->priv; |
304 | u8 buf[4]; | 304 | u8 buf[4]; |
@@ -485,12 +485,16 @@ static struct stv0297_config alps_tdee4_stv0297_config = { | |||
485 | /* try to figure out the frontend, each card/box can have on of the following list */ | 485 | /* try to figure out the frontend, each card/box can have on of the following list */ |
486 | int flexcop_frontend_init(struct flexcop_device *fc) | 486 | int flexcop_frontend_init(struct flexcop_device *fc) |
487 | { | 487 | { |
488 | struct dvb_frontend_ops *ops; | ||
489 | |||
488 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ | 490 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ |
489 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { | 491 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { |
490 | fc->fe->ops->set_voltage = flexcop_set_voltage; | 492 | ops = fc->fe->ops; |
493 | |||
494 | ops->set_voltage = flexcop_set_voltage; | ||
491 | 495 | ||
492 | fc->fe_sleep = fc->fe->ops->sleep; | 496 | fc->fe_sleep = ops->sleep; |
493 | fc->fe->ops->sleep = flexcop_sleep; | 497 | ops->sleep = flexcop_sleep; |
494 | 498 | ||
495 | fc->dev_type = FC_SKY; | 499 | fc->dev_type = FC_SKY; |
496 | info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); | 500 | info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); |
@@ -522,15 +526,17 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
522 | } else | 526 | } else |
523 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | 527 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ |
524 | if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { | 528 | if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { |
525 | fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | 529 | ops = fc->fe->ops; |
526 | fc->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst; | 530 | |
527 | fc->fe->ops->set_tone = flexcop_set_tone; | 531 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; |
528 | fc->fe->ops->set_voltage = flexcop_set_voltage; | 532 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; |
533 | ops->set_tone = flexcop_set_tone; | ||
534 | ops->set_voltage = flexcop_set_voltage; | ||
529 | 535 | ||
530 | fc->fe_sleep = fc->fe->ops->sleep; | 536 | fc->fe_sleep = ops->sleep; |
531 | fc->fe->ops->sleep = flexcop_sleep; | 537 | ops->sleep = flexcop_sleep; |
532 | 538 | ||
533 | fc->dev_type = FC_SKY_OLD; | 539 | fc->dev_type = FC_SKY_OLD; |
534 | info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); | 540 | info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); |
535 | } | 541 | } |
536 | 542 | ||
@@ -540,8 +546,9 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
540 | } else { | 546 | } else { |
541 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { | 547 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { |
542 | err("frontend registration failed!"); | 548 | err("frontend registration failed!"); |
543 | if (fc->fe->ops->release != NULL) | 549 | ops = fc->fe->ops; |
544 | fc->fe->ops->release(fc->fe); | 550 | if (ops->release != NULL) |
551 | ops->release(fc->fe); | ||
545 | fc->fe = NULL; | 552 | fc->fe = NULL; |
546 | return -EINVAL; | 553 | return -EINVAL; |
547 | } | 554 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h index 23cc6431e2b8..3153f9513c63 100644 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/drivers/media/dvb/b2c2/flexcop-reg.h | |||
@@ -39,11 +39,13 @@ extern const char *flexcop_device_names[]; | |||
39 | /* FlexCop IBI Registers */ | 39 | /* FlexCop IBI Registers */ |
40 | #if defined(__LITTLE_ENDIAN) | 40 | #if defined(__LITTLE_ENDIAN) |
41 | #include "flexcop_ibi_value_le.h" | 41 | #include "flexcop_ibi_value_le.h" |
42 | #elif defined(__BIG_ENDIAN) | 42 | #else |
43 | #if defined(__BIG_ENDIAN) | ||
43 | #include "flexcop_ibi_value_be.h" | 44 | #include "flexcop_ibi_value_be.h" |
44 | #else | 45 | #else |
45 | #error no endian defined | 46 | #error no endian defined |
46 | #endif | 47 | #endif |
48 | #endif | ||
47 | 49 | ||
48 | #define fc_data_Tag_ID_DVB 0x3e | 50 | #define fc_data_Tag_ID_DVB 0x3e |
49 | #define fc_data_Tag_ID_ATSC 0x3f | 51 | #define fc_data_Tag_ID_ATSC 0x3f |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 8977c7a313df..3a2ff1cc24b7 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -1341,30 +1341,40 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
1341 | return 0; | 1341 | return 0; |
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 1344 | static int dst_set_frontend(struct dvb_frontend* fe, |
1345 | struct dvb_frontend_parameters* p, | ||
1346 | unsigned int mode_flags, | ||
1347 | int *delay, | ||
1348 | fe_status_t *status) | ||
1345 | { | 1349 | { |
1346 | struct dst_state *state = fe->demodulator_priv; | 1350 | struct dst_state *state = fe->demodulator_priv; |
1347 | 1351 | ||
1348 | dst_set_freq(state, p->frequency); | 1352 | if (p != NULL) { |
1349 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | 1353 | dst_set_freq(state, p->frequency); |
1354 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1350 | 1355 | ||
1351 | if (state->dst_type == DST_TYPE_IS_SAT) { | 1356 | if (state->dst_type == DST_TYPE_IS_SAT) { |
1352 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | 1357 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) |
1353 | dst_set_inversion(state, p->inversion); | 1358 | dst_set_inversion(state, p->inversion); |
1354 | dst_set_fec(state, p->u.qpsk.fec_inner); | 1359 | dst_set_fec(state, p->u.qpsk.fec_inner); |
1355 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | 1360 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); |
1356 | dst_set_polarization(state); | 1361 | dst_set_polarization(state); |
1357 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); | 1362 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); |
1358 | 1363 | ||
1359 | } else if (state->dst_type == DST_TYPE_IS_TERR) | 1364 | } else if (state->dst_type == DST_TYPE_IS_TERR) |
1360 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | 1365 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); |
1361 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | 1366 | else if (state->dst_type == DST_TYPE_IS_CABLE) { |
1362 | dst_set_fec(state, p->u.qam.fec_inner); | 1367 | dst_set_fec(state, p->u.qam.fec_inner); |
1363 | dst_set_symbolrate(state, p->u.qam.symbol_rate); | 1368 | dst_set_symbolrate(state, p->u.qam.symbol_rate); |
1364 | dst_set_modulation(state, p->u.qam.modulation); | 1369 | dst_set_modulation(state, p->u.qam.modulation); |
1370 | } | ||
1371 | dst_write_tuna(fe); | ||
1365 | } | 1372 | } |
1366 | dst_write_tuna(fe); | ||
1367 | 1373 | ||
1374 | if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) | ||
1375 | dst_read_status(fe, status); | ||
1376 | |||
1377 | *delay = HZ/10; | ||
1368 | return 0; | 1378 | return 0; |
1369 | } | 1379 | } |
1370 | 1380 | ||
@@ -1445,7 +1455,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = { | |||
1445 | 1455 | ||
1446 | .release = dst_release, | 1456 | .release = dst_release, |
1447 | .init = dst_init, | 1457 | .init = dst_init, |
1448 | .set_frontend = dst_set_frontend, | 1458 | .tune = dst_set_frontend, |
1449 | .get_frontend = dst_get_frontend, | 1459 | .get_frontend = dst_get_frontend, |
1450 | .read_status = dst_read_status, | 1460 | .read_status = dst_read_status, |
1451 | .read_signal_strength = dst_read_signal_strength, | 1461 | .read_signal_strength = dst_read_signal_strength, |
@@ -1469,7 +1479,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1469 | 1479 | ||
1470 | .release = dst_release, | 1480 | .release = dst_release, |
1471 | .init = dst_init, | 1481 | .init = dst_init, |
1472 | .set_frontend = dst_set_frontend, | 1482 | .tune = dst_set_frontend, |
1473 | .get_frontend = dst_get_frontend, | 1483 | .get_frontend = dst_get_frontend, |
1474 | .read_status = dst_read_status, | 1484 | .read_status = dst_read_status, |
1475 | .read_signal_strength = dst_read_signal_strength, | 1485 | .read_signal_strength = dst_read_signal_strength, |
@@ -1496,7 +1506,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1496 | 1506 | ||
1497 | .release = dst_release, | 1507 | .release = dst_release, |
1498 | .init = dst_init, | 1508 | .init = dst_init, |
1499 | .set_frontend = dst_set_frontend, | 1509 | .tune = dst_set_frontend, |
1500 | .get_frontend = dst_get_frontend, | 1510 | .get_frontend = dst_get_frontend, |
1501 | .read_status = dst_read_status, | 1511 | .read_status = dst_read_status, |
1502 | .read_signal_strength = dst_read_signal_strength, | 1512 | .read_signal_strength = dst_read_signal_strength, |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 2239651969c8..c650b4bf7f5f 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -283,16 +283,17 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, | |||
283 | hw_buffer->msg[4] = 0x03; | 283 | hw_buffer->msg[4] = 0x03; |
284 | hw_buffer->msg[5] = length & 0xff; | 284 | hw_buffer->msg[5] = length & 0xff; |
285 | hw_buffer->msg[6] = 0x00; | 285 | hw_buffer->msg[6] = 0x00; |
286 | |||
286 | /* | 287 | /* |
287 | * Need to compute length for EN50221 section 8.3.2, for the time being | 288 | * Need to compute length for EN50221 section 8.3.2, for the time being |
288 | * assuming 8.3.2 is not applicable | 289 | * assuming 8.3.2 is not applicable |
289 | */ | 290 | */ |
290 | memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); | 291 | memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); |
291 | } | 292 | } |
293 | |||
292 | return 0; | 294 | return 0; |
293 | } | 295 | } |
294 | 296 | ||
295 | |||
296 | static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) | 297 | static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) |
297 | { | 298 | { |
298 | if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { | 299 | if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 77977e9c013e..01b4e0aac049 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -600,7 +600,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
600 | struct dst_state* state = NULL; | 600 | struct dst_state* state = NULL; |
601 | 601 | ||
602 | switch(type) { | 602 | switch(type) { |
603 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE | ||
604 | case BTTV_BOARD_DVICO_DVBT_LITE: | 603 | case BTTV_BOARD_DVICO_DVBT_LITE: |
605 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); | 604 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); |
606 | if (card->fe != NULL) { | 605 | if (card->fe != NULL) { |
@@ -608,22 +607,15 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
608 | card->fe->ops->info.frequency_max = 862000000; | 607 | card->fe->ops->info.frequency_max = 862000000; |
609 | } | 608 | } |
610 | break; | 609 | break; |
611 | #endif | ||
612 | 610 | ||
613 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE | ||
614 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | 611 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
615 | lgdt330x_reset(card); | 612 | lgdt330x_reset(card); |
616 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); | 613 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); |
617 | if (card->fe != NULL) | 614 | if (card->fe != NULL) |
618 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | 615 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); |
619 | break; | 616 | break; |
620 | #endif | ||
621 | 617 | ||
622 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
623 | case BTTV_BOARD_TWINHAN_VP3021: | ||
624 | #else | ||
625 | case BTTV_BOARD_NEBULA_DIGITV: | 618 | case BTTV_BOARD_NEBULA_DIGITV: |
626 | #endif | ||
627 | /* | 619 | /* |
628 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); | 620 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); |
629 | * this would be a cleaner solution than trying each frontend in turn. | 621 | * this would be a cleaner solution than trying each frontend in turn. |
@@ -812,9 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
812 | card->irq_err_ignore = 0; | 804 | card->irq_err_ignore = 0; |
813 | break; | 805 | break; |
814 | 806 | ||
815 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE | ||
816 | case BTTV_BOARD_DVICO_DVBT_LITE: | 807 | case BTTV_BOARD_DVICO_DVBT_LITE: |
817 | #endif | ||
818 | card->gpio_mode = 0x0400C060; | 808 | card->gpio_mode = 0x0400C060; |
819 | card->op_sync_orin = 0; | 809 | card->op_sync_orin = 0; |
820 | card->irq_err_ignore = 0; | 810 | card->irq_err_ignore = 0; |
@@ -823,19 +813,13 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
823 | * DA_APP(parallel) */ | 813 | * DA_APP(parallel) */ |
824 | break; | 814 | break; |
825 | 815 | ||
826 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE | ||
827 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | 816 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
828 | #endif | ||
829 | card->gpio_mode = 0x0400c060; | 817 | card->gpio_mode = 0x0400c060; |
830 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 818 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
831 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | 819 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
832 | break; | 820 | break; |
833 | 821 | ||
834 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
835 | case BTTV_BOARD_TWINHAN_VP3021: | ||
836 | #else | ||
837 | case BTTV_BOARD_NEBULA_DIGITV: | 822 | case BTTV_BOARD_NEBULA_DIGITV: |
838 | #endif | ||
839 | case BTTV_BOARD_AVDVBT_761: | 823 | case BTTV_BOARD_AVDVBT_761: |
840 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); | 824 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); |
841 | card->op_sync_orin = 0; | 825 | card->op_sync_orin = 0; |
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig index 7cf4c4a888ec..6018fcdba1e6 100644 --- a/drivers/media/dvb/cinergyT2/Kconfig +++ b/drivers/media/dvb/cinergyT2/Kconfig | |||
@@ -21,35 +21,35 @@ config DVB_CINERGYT2_TUNING | |||
21 | config DVB_CINERGYT2_STREAM_URB_COUNT | 21 | config DVB_CINERGYT2_STREAM_URB_COUNT |
22 | int "Number of queued USB Request Blocks for Highspeed Stream Transfers" | 22 | int "Number of queued USB Request Blocks for Highspeed Stream Transfers" |
23 | depends on DVB_CINERGYT2_TUNING | 23 | depends on DVB_CINERGYT2_TUNING |
24 | default "32" | 24 | default "32" |
25 | help | 25 | help |
26 | USB Request Blocks for Highspeed Stream transfers are scheduled in | 26 | USB Request Blocks for Highspeed Stream transfers are scheduled in |
27 | a queue for the Host Controller. | 27 | a queue for the Host Controller. |
28 | 28 | ||
29 | Usually the default value is a safe choice. | 29 | Usually the default value is a safe choice. |
30 | 30 | ||
31 | You may increase this number if you are using this device in a | 31 | You may increase this number if you are using this device in a |
32 | Server Environment with many high-traffic USB Highspeed devices | 32 | Server Environment with many high-traffic USB Highspeed devices |
33 | sharing the same USB bus. | 33 | sharing the same USB bus. |
34 | 34 | ||
35 | 35 | ||
36 | config DVB_CINERGYT2_STREAM_BUF_SIZE | 36 | config DVB_CINERGYT2_STREAM_BUF_SIZE |
37 | int "Size of URB Stream Buffers for Highspeed Transfers" | 37 | int "Size of URB Stream Buffers for Highspeed Transfers" |
38 | depends on DVB_CINERGYT2_TUNING | 38 | depends on DVB_CINERGYT2_TUNING |
39 | default "512" | 39 | default "512" |
40 | help | 40 | help |
41 | Should be a multiple of native buffer size of 512 bytes. | 41 | Should be a multiple of native buffer size of 512 bytes. |
42 | Default value is a safe choice. | 42 | Default value is a safe choice. |
43 | 43 | ||
44 | You may increase this number if you are using this device in a | 44 | You may increase this number if you are using this device in a |
45 | Server Environment with many high-traffic USB Highspeed devices | 45 | Server Environment with many high-traffic USB Highspeed devices |
46 | sharing the same USB bus. | 46 | sharing the same USB bus. |
47 | 47 | ||
48 | 48 | ||
49 | config DVB_CINERGYT2_QUERY_INTERVAL | 49 | config DVB_CINERGYT2_QUERY_INTERVAL |
50 | int "Status update interval [milliseconds]" | 50 | int "Status update interval [milliseconds]" |
51 | depends on DVB_CINERGYT2_TUNING | 51 | depends on DVB_CINERGYT2_TUNING |
52 | default "250" | 52 | default "250" |
53 | help | 53 | help |
54 | This is the interval for status readouts from the demodulator. | 54 | This is the interval for status readouts from the demodulator. |
55 | You may try lower values if you need more responsive signal quality | 55 | You may try lower values if you need more responsive signal quality |
@@ -64,9 +64,9 @@ config DVB_CINERGYT2_QUERY_INTERVAL | |||
64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | 64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE |
65 | bool "Register the onboard IR Remote Control Receiver as Input Device" | 65 | bool "Register the onboard IR Remote Control Receiver as Input Device" |
66 | depends on DVB_CINERGYT2_TUNING | 66 | depends on DVB_CINERGYT2_TUNING |
67 | default "yes" | 67 | default "yes" |
68 | help | 68 | help |
69 | Enable this option if you want to use the onboard Infrared Remote | 69 | Enable this option if you want to use the onboard Infrared Remote |
70 | Control Receiver as Linux-Input device. | 70 | Control Receiver as Linux-Input device. |
71 | 71 | ||
72 | Right now only the keycode table for the default Remote Control | 72 | Right now only the keycode table for the default Remote Control |
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | |||
77 | config DVB_CINERGYT2_RC_QUERY_INTERVAL | 77 | config DVB_CINERGYT2_RC_QUERY_INTERVAL |
78 | int "Infrared Remote Controller update interval [milliseconds]" | 78 | int "Infrared Remote Controller update interval [milliseconds]" |
79 | depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | 79 | depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE |
80 | default "50" | 80 | default "50" |
81 | help | 81 | help |
82 | If you have a very fast-repeating remote control you can try lower | 82 | If you have a very fast-repeating remote control you can try lower |
83 | values, for normal consumer receivers the default value should be | 83 | values, for normal consumer receivers the default value should be |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 1d69bf031fb9..c4b4c5b6b7c8 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -131,6 +131,8 @@ struct cinergyt2 { | |||
131 | 131 | ||
132 | wait_queue_head_t poll_wq; | 132 | wait_queue_head_t poll_wq; |
133 | int pending_fe_events; | 133 | int pending_fe_events; |
134 | int disconnect_pending; | ||
135 | atomic_t inuse; | ||
134 | 136 | ||
135 | void *streambuf; | 137 | void *streambuf; |
136 | dma_addr_t streambuf_dmahandle; | 138 | dma_addr_t streambuf_dmahandle; |
@@ -343,7 +345,7 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
343 | struct dvb_demux *demux = dvbdmxfeed->demux; | 345 | struct dvb_demux *demux = dvbdmxfeed->demux; |
344 | struct cinergyt2 *cinergyt2 = demux->priv; | 346 | struct cinergyt2 *cinergyt2 = demux->priv; |
345 | 347 | ||
346 | if (down_interruptible(&cinergyt2->sem)) | 348 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
347 | return -ERESTARTSYS; | 349 | return -ERESTARTSYS; |
348 | 350 | ||
349 | if (cinergyt2->streaming == 0) | 351 | if (cinergyt2->streaming == 0) |
@@ -359,7 +361,7 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
359 | struct dvb_demux *demux = dvbdmxfeed->demux; | 361 | struct dvb_demux *demux = dvbdmxfeed->demux; |
360 | struct cinergyt2 *cinergyt2 = demux->priv; | 362 | struct cinergyt2 *cinergyt2 = demux->priv; |
361 | 363 | ||
362 | if (down_interruptible(&cinergyt2->sem)) | 364 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
363 | return -ERESTARTSYS; | 365 | return -ERESTARTSYS; |
364 | 366 | ||
365 | if (--cinergyt2->streaming == 0) | 367 | if (--cinergyt2->streaming == 0) |
@@ -479,23 +481,37 @@ static int cinergyt2_open (struct inode *inode, struct file *file) | |||
479 | { | 481 | { |
480 | struct dvb_device *dvbdev = file->private_data; | 482 | struct dvb_device *dvbdev = file->private_data; |
481 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 483 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
482 | int err; | 484 | int err = -ERESTARTSYS; |
483 | 485 | ||
484 | if ((err = dvb_generic_open(inode, file))) | 486 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
487 | return -ERESTARTSYS; | ||
488 | |||
489 | if ((err = dvb_generic_open(inode, file))) { | ||
490 | up(&cinergyt2->sem); | ||
485 | return err; | 491 | return err; |
492 | } | ||
486 | 493 | ||
487 | if (down_interruptible(&cinergyt2->sem)) | ||
488 | return -ERESTARTSYS; | ||
489 | 494 | ||
490 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 495 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { |
491 | cinergyt2_sleep(cinergyt2, 0); | 496 | cinergyt2_sleep(cinergyt2, 0); |
492 | schedule_delayed_work(&cinergyt2->query_work, HZ/2); | 497 | schedule_delayed_work(&cinergyt2->query_work, HZ/2); |
493 | } | 498 | } |
494 | 499 | ||
500 | atomic_inc(&cinergyt2->inuse); | ||
501 | |||
495 | up(&cinergyt2->sem); | 502 | up(&cinergyt2->sem); |
496 | return 0; | 503 | return 0; |
497 | } | 504 | } |
498 | 505 | ||
506 | static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) | ||
507 | { | ||
508 | dvb_unregister_device(cinergyt2->fedev); | ||
509 | dvb_unregister_adapter(&cinergyt2->adapter); | ||
510 | |||
511 | cinergyt2_free_stream_urbs(cinergyt2); | ||
512 | kfree(cinergyt2); | ||
513 | } | ||
514 | |||
499 | static int cinergyt2_release (struct inode *inode, struct file *file) | 515 | static int cinergyt2_release (struct inode *inode, struct file *file) |
500 | { | 516 | { |
501 | struct dvb_device *dvbdev = file->private_data; | 517 | struct dvb_device *dvbdev = file->private_data; |
@@ -504,7 +520,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) | |||
504 | if (down_interruptible(&cinergyt2->sem)) | 520 | if (down_interruptible(&cinergyt2->sem)) |
505 | return -ERESTARTSYS; | 521 | return -ERESTARTSYS; |
506 | 522 | ||
507 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 523 | if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { |
508 | cancel_delayed_work(&cinergyt2->query_work); | 524 | cancel_delayed_work(&cinergyt2->query_work); |
509 | flush_scheduled_work(); | 525 | flush_scheduled_work(); |
510 | cinergyt2_sleep(cinergyt2, 1); | 526 | cinergyt2_sleep(cinergyt2, 1); |
@@ -512,6 +528,11 @@ static int cinergyt2_release (struct inode *inode, struct file *file) | |||
512 | 528 | ||
513 | up(&cinergyt2->sem); | 529 | up(&cinergyt2->sem); |
514 | 530 | ||
531 | if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { | ||
532 | warn("delayed unregister in release"); | ||
533 | cinergyt2_unregister(cinergyt2); | ||
534 | } | ||
535 | |||
515 | return dvb_generic_release(inode, file); | 536 | return dvb_generic_release(inode, file); |
516 | } | 537 | } |
517 | 538 | ||
@@ -519,7 +540,14 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct | |||
519 | { | 540 | { |
520 | struct dvb_device *dvbdev = file->private_data; | 541 | struct dvb_device *dvbdev = file->private_data; |
521 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 542 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
543 | |||
544 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | ||
545 | return -ERESTARTSYS; | ||
546 | |||
522 | poll_wait(file, &cinergyt2->poll_wq, wait); | 547 | poll_wait(file, &cinergyt2->poll_wq, wait); |
548 | |||
549 | up(&cinergyt2->sem); | ||
550 | |||
523 | return (POLLIN | POLLRDNORM | POLLPRI); | 551 | return (POLLIN | POLLRDNORM | POLLPRI); |
524 | } | 552 | } |
525 | 553 | ||
@@ -564,10 +592,15 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
564 | (__u16 __user *) arg); | 592 | (__u16 __user *) arg); |
565 | 593 | ||
566 | case FE_READ_UNCORRECTED_BLOCKS: | 594 | case FE_READ_UNCORRECTED_BLOCKS: |
567 | /* UNC are already converted to host byte order... */ | 595 | { |
568 | return put_user(stat->uncorrected_block_count, | 596 | uint32_t unc_count; |
569 | (__u32 __user *) arg); | 597 | |
598 | unc_count = stat->uncorrected_block_count; | ||
599 | stat->uncorrected_block_count = 0; | ||
570 | 600 | ||
601 | /* UNC are already converted to host byte order... */ | ||
602 | return put_user(unc_count,(__u32 __user *) arg); | ||
603 | } | ||
571 | case FE_SET_FRONTEND: | 604 | case FE_SET_FRONTEND: |
572 | { | 605 | { |
573 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; | 606 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; |
@@ -580,7 +613,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
580 | if (copy_from_user(&p, (void __user*) arg, sizeof(p))) | 613 | if (copy_from_user(&p, (void __user*) arg, sizeof(p))) |
581 | return -EFAULT; | 614 | return -EFAULT; |
582 | 615 | ||
583 | if (down_interruptible(&cinergyt2->sem)) | 616 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
584 | return -ERESTARTSYS; | 617 | return -ERESTARTSYS; |
585 | 618 | ||
586 | param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; | 619 | param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; |
@@ -691,7 +724,7 @@ static void cinergyt2_query_rc (void *data) | |||
691 | struct cinergyt2_rc_event rc_events[12]; | 724 | struct cinergyt2_rc_event rc_events[12]; |
692 | int n, len, i; | 725 | int n, len, i; |
693 | 726 | ||
694 | if (down_interruptible(&cinergyt2->sem)) | 727 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
695 | return; | 728 | return; |
696 | 729 | ||
697 | len = cinergyt2_command(cinergyt2, buf, sizeof(buf), | 730 | len = cinergyt2_command(cinergyt2, buf, sizeof(buf), |
@@ -786,7 +819,6 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
786 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) | 819 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) |
787 | { | 820 | { |
788 | cancel_delayed_work(&cinergyt2->rc_query_work); | 821 | cancel_delayed_work(&cinergyt2->rc_query_work); |
789 | flush_scheduled_work(); | ||
790 | input_unregister_device(cinergyt2->rc_input_dev); | 822 | input_unregister_device(cinergyt2->rc_input_dev); |
791 | } | 823 | } |
792 | 824 | ||
@@ -817,7 +849,7 @@ static void cinergyt2_query (void *data) | |||
817 | uint8_t lock_bits; | 849 | uint8_t lock_bits; |
818 | uint32_t unc; | 850 | uint32_t unc; |
819 | 851 | ||
820 | if (down_interruptible(&cinergyt2->sem)) | 852 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
821 | return; | 853 | return; |
822 | 854 | ||
823 | unc = s->uncorrected_block_count; | 855 | unc = s->uncorrected_block_count; |
@@ -917,28 +949,25 @@ static void cinergyt2_disconnect (struct usb_interface *intf) | |||
917 | { | 949 | { |
918 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 950 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
919 | 951 | ||
920 | if (down_interruptible(&cinergyt2->sem)) | 952 | flush_scheduled_work(); |
921 | return; | ||
922 | 953 | ||
923 | cinergyt2_unregister_rc(cinergyt2); | 954 | cinergyt2_unregister_rc(cinergyt2); |
924 | 955 | ||
956 | cancel_delayed_work(&cinergyt2->query_work); | ||
957 | wake_up_interruptible(&cinergyt2->poll_wq); | ||
958 | |||
925 | cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); | 959 | cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); |
926 | dvb_net_release(&cinergyt2->dvbnet); | 960 | cinergyt2->disconnect_pending = 1; |
927 | dvb_dmxdev_release(&cinergyt2->dmxdev); | ||
928 | dvb_dmx_release(&cinergyt2->demux); | ||
929 | dvb_unregister_device(cinergyt2->fedev); | ||
930 | dvb_unregister_adapter(&cinergyt2->adapter); | ||
931 | 961 | ||
932 | cinergyt2_free_stream_urbs(cinergyt2); | 962 | if (!atomic_read(&cinergyt2->inuse)) |
933 | up(&cinergyt2->sem); | 963 | cinergyt2_unregister(cinergyt2); |
934 | kfree(cinergyt2); | ||
935 | } | 964 | } |
936 | 965 | ||
937 | static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) | 966 | static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) |
938 | { | 967 | { |
939 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 968 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
940 | 969 | ||
941 | if (down_interruptible(&cinergyt2->sem)) | 970 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
942 | return -ERESTARTSYS; | 971 | return -ERESTARTSYS; |
943 | 972 | ||
944 | if (state.event > PM_EVENT_ON) { | 973 | if (state.event > PM_EVENT_ON) { |
@@ -961,7 +990,7 @@ static int cinergyt2_resume (struct usb_interface *intf) | |||
961 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 990 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
962 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; | 991 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; |
963 | 992 | ||
964 | if (down_interruptible(&cinergyt2->sem)) | 993 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
965 | return -ERESTARTSYS; | 994 | return -ERESTARTSYS; |
966 | 995 | ||
967 | if (!cinergyt2->sleeping) { | 996 | if (!cinergyt2->sleeping) { |
@@ -1014,4 +1043,3 @@ module_exit (cinergyt2_exit); | |||
1014 | 1043 | ||
1015 | MODULE_LICENSE("GPL"); | 1044 | MODULE_LICENSE("GPL"); |
1016 | MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); | 1045 | MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); |
1017 | |||
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig index a9a7b3421048..12ee912a5705 100644 --- a/drivers/media/dvb/dvb-core/Kconfig +++ b/drivers/media/dvb/dvb-core/Kconfig | |||
@@ -5,7 +5,7 @@ config DVB_CORE | |||
5 | help | 5 | help |
6 | DVB core utility functions for device handling, software fallbacks etc. | 6 | DVB core utility functions for device handling, software fallbacks etc. |
7 | Say Y when you have a DVB card and want to use it. Say Y if your want | 7 | Say Y when you have a DVB card and want to use it. Say Y if your want |
8 | to build your drivers outside the kernel, but need the DVB core. All | 8 | to build your drivers outside the kernel, but need the DVB core. All |
9 | in-kernel drivers will select this automatically if needed. | 9 | in-kernel drivers will select this automatically if needed. |
10 | If unsure say N. | 10 | If unsure say N. |
11 | 11 | ||
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index c6baac20f529..7adb50c1e8eb 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ | 5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ |
6 | dvb_ca_en50221.o dvb_frontend.o \ | 6 | dvb_ca_en50221.o dvb_frontend.o \ |
7 | dvb_net.o dvb_ringbuffer.o | 7 | dvb_net.o dvb_ringbuffer.o |
8 | 8 | ||
9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o | 9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o |
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 5956c35d34ac..4bb779aeff6a 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -1745,9 +1745,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) | |||
1745 | 1745 | ||
1746 | for (i = 0; i < ca->slot_count; i++) { | 1746 | for (i = 0; i < ca->slot_count; i++) { |
1747 | dvb_ca_en50221_slot_shutdown(ca, i); | 1747 | dvb_ca_en50221_slot_shutdown(ca, i); |
1748 | if (ca->slot_info[i].rx_buffer.data != NULL) { | 1748 | vfree(ca->slot_info[i].rx_buffer.data); |
1749 | vfree(ca->slot_info[i].rx_buffer.data); | ||
1750 | } | ||
1751 | } | 1749 | } |
1752 | kfree(ca->slot_info); | 1750 | kfree(ca->slot_info); |
1753 | dvb_unregister_device(ca->dvbdev); | 1751 | dvb_unregister_device(ca->dvbdev); |
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c index c49fd0bd7181..772003fb1821 100644 --- a/drivers/media/dvb/dvb-core/dvb_filter.c +++ b/drivers/media/dvb/dvb-core/dvb_filter.c | |||
@@ -409,16 +409,16 @@ static u8 *skip_pes_header(u8 **bufp) | |||
409 | 409 | ||
410 | if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ | 410 | if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ |
411 | if (buf[7] & PTS_ONLY) | 411 | if (buf[7] & PTS_ONLY) |
412 | pts = buf+9; | 412 | pts = buf+9; |
413 | else pts = NULL; | 413 | else pts = NULL; |
414 | buf = inbuf + 9 + inbuf[8]; | 414 | buf = inbuf + 9 + inbuf[8]; |
415 | } else { /* mpeg1 */ | 415 | } else { /* mpeg1 */ |
416 | for (buf = inbuf + 6; *buf == 0xff; buf++) | 416 | for (buf = inbuf + 6; *buf == 0xff; buf++) |
417 | if (buf == inbuf + 6 + 16) { | 417 | if (buf == inbuf + 6 + 16) { |
418 | break; | 418 | break; |
419 | } | 419 | } |
420 | if ((*buf & 0xc0) == 0x40) | 420 | if ((*buf & 0xc0) == 0x40) |
421 | buf += 2; | 421 | buf += 2; |
422 | skip = mpeg1_skip_table [*buf >> 4]; | 422 | skip = mpeg1_skip_table [*buf >> 4]; |
423 | if (skip == 5 || skip == 10) pts = buf; | 423 | if (skip == 5 || skip == 10) pts = buf; |
424 | else pts = NULL; | 424 | else pts = NULL; |
@@ -529,9 +529,9 @@ static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_t | |||
529 | pic->picture_header = 0; | 529 | pic->picture_header = 0; |
530 | pic->sequence_header_data | 530 | pic->sequence_header_data |
531 | = ( INIT_HORIZONTAL_SIZE << 20 ) | 531 | = ( INIT_HORIZONTAL_SIZE << 20 ) |
532 | | ( INIT_VERTICAL_SIZE << 8 ) | 532 | | ( INIT_VERTICAL_SIZE << 8 ) |
533 | | ( INIT_ASPECT_RATIO << 4 ) | 533 | | ( INIT_ASPECT_RATIO << 4 ) |
534 | | ( INIT_FRAME_RATE ); | 534 | | ( INIT_FRAME_RATE ); |
535 | pic->mpeg1_flag = 0; | 535 | pic->mpeg1_flag = 0; |
536 | pic->vinfo.horizontal_size | 536 | pic->vinfo.horizontal_size |
537 | = INIT_DISP_HORIZONTAL_SIZE; | 537 | = INIT_DISP_HORIZONTAL_SIZE; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 95ea5095e07e..4a08c4ab6730 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -92,6 +92,7 @@ static DECLARE_MUTEX(frontend_mutex); | |||
92 | 92 | ||
93 | struct dvb_frontend_private { | 93 | struct dvb_frontend_private { |
94 | 94 | ||
95 | /* thread/frontend values */ | ||
95 | struct dvb_device *dvbdev; | 96 | struct dvb_device *dvbdev; |
96 | struct dvb_frontend_parameters parameters; | 97 | struct dvb_frontend_parameters parameters; |
97 | struct dvb_fe_events events; | 98 | struct dvb_fe_events events; |
@@ -100,20 +101,25 @@ struct dvb_frontend_private { | |||
100 | wait_queue_head_t wait_queue; | 101 | wait_queue_head_t wait_queue; |
101 | pid_t thread_pid; | 102 | pid_t thread_pid; |
102 | unsigned long release_jiffies; | 103 | unsigned long release_jiffies; |
103 | int state; | 104 | unsigned int exit; |
104 | int bending; | 105 | unsigned int wakeup; |
105 | int lnb_drift; | ||
106 | int inversion; | ||
107 | int auto_step; | ||
108 | int auto_sub_step; | ||
109 | int started_auto_step; | ||
110 | int min_delay; | ||
111 | int max_drift; | ||
112 | int step_size; | ||
113 | int exit; | ||
114 | int wakeup; | ||
115 | fe_status_t status; | 106 | fe_status_t status; |
116 | fe_sec_tone_mode_t tone; | 107 | unsigned long tune_mode_flags; |
108 | unsigned int delay; | ||
109 | |||
110 | /* swzigzag values */ | ||
111 | unsigned int state; | ||
112 | unsigned int bending; | ||
113 | int lnb_drift; | ||
114 | unsigned int inversion; | ||
115 | unsigned int auto_step; | ||
116 | unsigned int auto_sub_step; | ||
117 | unsigned int started_auto_step; | ||
118 | unsigned int min_delay; | ||
119 | unsigned int max_drift; | ||
120 | unsigned int step_size; | ||
121 | int quality; | ||
122 | unsigned int check_wrapped; | ||
117 | }; | 123 | }; |
118 | 124 | ||
119 | 125 | ||
@@ -208,21 +214,21 @@ static void dvb_frontend_init(struct dvb_frontend *fe) | |||
208 | fe->ops->init(fe); | 214 | fe->ops->init(fe); |
209 | } | 215 | } |
210 | 216 | ||
211 | static void update_delay(int *quality, int *delay, int min_delay, int locked) | 217 | static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) |
212 | { | 218 | { |
213 | int q2; | 219 | int q2; |
214 | 220 | ||
215 | dprintk ("%s\n", __FUNCTION__); | 221 | dprintk ("%s\n", __FUNCTION__); |
216 | 222 | ||
217 | if (locked) | 223 | if (locked) |
218 | (*quality) = (*quality * 220 + 36*256) / 256; | 224 | (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; |
219 | else | 225 | else |
220 | (*quality) = (*quality * 220 + 0) / 256; | 226 | (fepriv->quality) = (fepriv->quality * 220 + 0) / 256; |
221 | 227 | ||
222 | q2 = *quality - 128; | 228 | q2 = fepriv->quality - 128; |
223 | q2 *= q2; | 229 | q2 *= q2; |
224 | 230 | ||
225 | *delay = min_delay + q2 * HZ / (128*128); | 231 | fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128); |
226 | } | 232 | } |
227 | 233 | ||
228 | /** | 234 | /** |
@@ -232,7 +238,7 @@ static void update_delay(int *quality, int *delay, int min_delay, int locked) | |||
232 | * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT | 238 | * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT |
233 | * @returns Number of complete iterations that have been performed. | 239 | * @returns Number of complete iterations that have been performed. |
234 | */ | 240 | */ |
235 | static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) | 241 | static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped) |
236 | { | 242 | { |
237 | int autoinversion; | 243 | int autoinversion; |
238 | int ready = 0; | 244 | int ready = 0; |
@@ -321,6 +327,129 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) | |||
321 | return 0; | 327 | return 0; |
322 | } | 328 | } |
323 | 329 | ||
330 | static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | ||
331 | { | ||
332 | fe_status_t s; | ||
333 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | ||
334 | |||
335 | /* if we've got no parameters, just keep idling */ | ||
336 | if (fepriv->state & FESTATE_IDLE) { | ||
337 | fepriv->delay = 3*HZ; | ||
338 | fepriv->quality = 0; | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | /* in SCAN mode, we just set the frontend when asked and leave it alone */ | ||
343 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { | ||
344 | if (fepriv->state & FESTATE_RETUNE) { | ||
345 | if (fe->ops->set_frontend) | ||
346 | fe->ops->set_frontend(fe, &fepriv->parameters); | ||
347 | fepriv->state = FESTATE_TUNED; | ||
348 | } | ||
349 | fepriv->delay = 3*HZ; | ||
350 | fepriv->quality = 0; | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* get the frontend status */ | ||
355 | if (fepriv->state & FESTATE_RETUNE) { | ||
356 | s = 0; | ||
357 | } else { | ||
358 | if (fe->ops->read_status) | ||
359 | fe->ops->read_status(fe, &s); | ||
360 | if (s != fepriv->status) { | ||
361 | dvb_frontend_add_event(fe, s); | ||
362 | fepriv->status = s; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | /* if we're not tuned, and we have a lock, move to the TUNED state */ | ||
367 | if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { | ||
368 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
369 | fepriv->state = FESTATE_TUNED; | ||
370 | |||
371 | /* if we're tuned, then we have determined the correct inversion */ | ||
372 | if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | ||
373 | (fepriv->parameters.inversion == INVERSION_AUTO)) { | ||
374 | fepriv->parameters.inversion = fepriv->inversion; | ||
375 | } | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | /* if we are tuned already, check we're still locked */ | ||
380 | if (fepriv->state & FESTATE_TUNED) { | ||
381 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
382 | |||
383 | /* we're tuned, and the lock is still good... */ | ||
384 | if (s & FE_HAS_LOCK) { | ||
385 | return; | ||
386 | } else { /* if we _WERE_ tuned, but now don't have a lock */ | ||
387 | fepriv->state = FESTATE_ZIGZAG_FAST; | ||
388 | fepriv->started_auto_step = fepriv->auto_step; | ||
389 | fepriv->check_wrapped = 0; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | /* don't actually do anything if we're in the LOSTLOCK state, | ||
394 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ | ||
395 | if ((fepriv->state & FESTATE_LOSTLOCK) && | ||
396 | (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { | ||
397 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
398 | return; | ||
399 | } | ||
400 | |||
401 | /* don't do anything if we're in the DISEQC state, since this | ||
402 | * might be someone with a motorized dish controlled by DISEQC. | ||
403 | * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ | ||
404 | if (fepriv->state & FESTATE_DISEQC) { | ||
405 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | /* if we're in the RETUNE state, set everything up for a brand | ||
410 | * new scan, keeping the current inversion setting, as the next | ||
411 | * tune is _very_ likely to require the same */ | ||
412 | if (fepriv->state & FESTATE_RETUNE) { | ||
413 | fepriv->lnb_drift = 0; | ||
414 | fepriv->auto_step = 0; | ||
415 | fepriv->auto_sub_step = 0; | ||
416 | fepriv->started_auto_step = 0; | ||
417 | fepriv->check_wrapped = 0; | ||
418 | } | ||
419 | |||
420 | /* fast zigzag. */ | ||
421 | if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { | ||
422 | fepriv->delay = fepriv->min_delay; | ||
423 | |||
424 | /* peform a tune */ | ||
425 | if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { | ||
426 | /* OK, if we've run out of trials at the fast speed. | ||
427 | * Drop back to slow for the _next_ attempt */ | ||
428 | fepriv->state = FESTATE_SEARCHING_SLOW; | ||
429 | fepriv->started_auto_step = fepriv->auto_step; | ||
430 | return; | ||
431 | } | ||
432 | fepriv->check_wrapped = 1; | ||
433 | |||
434 | /* if we've just retuned, enter the ZIGZAG_FAST state. | ||
435 | * This ensures we cannot return from an | ||
436 | * FE_SET_FRONTEND ioctl before the first frontend tune | ||
437 | * occurs */ | ||
438 | if (fepriv->state & FESTATE_RETUNE) { | ||
439 | fepriv->state = FESTATE_TUNING_FAST; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | /* slow zigzag */ | ||
444 | if (fepriv->state & FESTATE_SEARCHING_SLOW) { | ||
445 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
446 | |||
447 | /* Note: don't bother checking for wrapping; we stay in this | ||
448 | * state until we get a lock */ | ||
449 | dvb_frontend_swzigzag_autotune(fe, 0); | ||
450 | } | ||
451 | } | ||
452 | |||
324 | static int dvb_frontend_is_exiting(struct dvb_frontend *fe) | 453 | static int dvb_frontend_is_exiting(struct dvb_frontend *fe) |
325 | { | 454 | { |
326 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 455 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
@@ -330,7 +459,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) | |||
330 | 459 | ||
331 | if (fepriv->dvbdev->writers == 1) | 460 | if (fepriv->dvbdev->writers == 1) |
332 | if (time_after(jiffies, fepriv->release_jiffies + | 461 | if (time_after(jiffies, fepriv->release_jiffies + |
333 | dvb_shutdown_timeout * HZ)) | 462 | dvb_shutdown_timeout * HZ)) |
334 | return 1; | 463 | return 1; |
335 | 464 | ||
336 | return 0; | 465 | return 0; |
@@ -355,18 +484,14 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) | |||
355 | wake_up_interruptible(&fepriv->wait_queue); | 484 | wake_up_interruptible(&fepriv->wait_queue); |
356 | } | 485 | } |
357 | 486 | ||
358 | /* | ||
359 | * FIXME: use linux/kthread.h | ||
360 | */ | ||
361 | static int dvb_frontend_thread(void *data) | 487 | static int dvb_frontend_thread(void *data) |
362 | { | 488 | { |
363 | struct dvb_frontend *fe = data; | 489 | struct dvb_frontend *fe = data; |
364 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 490 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
365 | unsigned long timeout; | 491 | unsigned long timeout; |
366 | char name [15]; | 492 | char name [15]; |
367 | int quality = 0, delay = 3*HZ; | ||
368 | fe_status_t s; | 493 | fe_status_t s; |
369 | int check_wrapped = 0; | 494 | struct dvb_frontend_parameters *params; |
370 | 495 | ||
371 | dprintk("%s\n", __FUNCTION__); | 496 | dprintk("%s\n", __FUNCTION__); |
372 | 497 | ||
@@ -377,6 +502,9 @@ static int dvb_frontend_thread(void *data) | |||
377 | sigfillset(¤t->blocked); | 502 | sigfillset(¤t->blocked); |
378 | unlock_kernel(); | 503 | unlock_kernel(); |
379 | 504 | ||
505 | fepriv->check_wrapped = 0; | ||
506 | fepriv->quality = 0; | ||
507 | fepriv->delay = 3*HZ; | ||
380 | fepriv->status = 0; | 508 | fepriv->status = 0; |
381 | dvb_frontend_init(fe); | 509 | dvb_frontend_init(fe); |
382 | fepriv->wakeup = 0; | 510 | fepriv->wakeup = 0; |
@@ -386,7 +514,7 @@ static int dvb_frontend_thread(void *data) | |||
386 | 514 | ||
387 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, | 515 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, |
388 | dvb_frontend_should_wakeup(fe), | 516 | dvb_frontend_should_wakeup(fe), |
389 | delay); | 517 | fepriv->delay); |
390 | if (0 != dvb_frontend_is_exiting(fe)) { | 518 | if (0 != dvb_frontend_is_exiting(fe)) { |
391 | /* got signal or quitting */ | 519 | /* got signal or quitting */ |
392 | break; | 520 | break; |
@@ -397,108 +525,22 @@ static int dvb_frontend_thread(void *data) | |||
397 | if (down_interruptible(&fepriv->sem)) | 525 | if (down_interruptible(&fepriv->sem)) |
398 | break; | 526 | break; |
399 | 527 | ||
400 | /* if we've got no parameters, just keep idling */ | 528 | /* do an iteration of the tuning loop */ |
401 | if (fepriv->state & FESTATE_IDLE) { | 529 | if (fe->ops->tune) { |
402 | delay = 3*HZ; | 530 | /* have we been asked to retune? */ |
403 | quality = 0; | 531 | params = NULL; |
404 | continue; | 532 | if (fepriv->state & FESTATE_RETUNE) { |
405 | } | 533 | params = &fepriv->parameters; |
534 | fepriv->state = FESTATE_TUNED; | ||
535 | } | ||
406 | 536 | ||
407 | /* get the frontend status */ | 537 | fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); |
408 | if (fepriv->state & FESTATE_RETUNE) { | ||
409 | s = 0; | ||
410 | } else { | ||
411 | if (fe->ops->read_status) | ||
412 | fe->ops->read_status(fe, &s); | ||
413 | if (s != fepriv->status) { | 538 | if (s != fepriv->status) { |
414 | dvb_frontend_add_event(fe, s); | 539 | dvb_frontend_add_event(fe, s); |
415 | fepriv->status = s; | 540 | fepriv->status = s; |
416 | } | 541 | } |
417 | } | 542 | } else { |
418 | /* if we're not tuned, and we have a lock, move to the TUNED state */ | 543 | dvb_frontend_swzigzag(fe); |
419 | if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { | ||
420 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
421 | fepriv->state = FESTATE_TUNED; | ||
422 | |||
423 | /* if we're tuned, then we have determined the correct inversion */ | ||
424 | if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | ||
425 | (fepriv->parameters.inversion == INVERSION_AUTO)) { | ||
426 | fepriv->parameters.inversion = fepriv->inversion; | ||
427 | } | ||
428 | continue; | ||
429 | } | ||
430 | |||
431 | /* if we are tuned already, check we're still locked */ | ||
432 | if (fepriv->state & FESTATE_TUNED) { | ||
433 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
434 | |||
435 | /* we're tuned, and the lock is still good... */ | ||
436 | if (s & FE_HAS_LOCK) | ||
437 | continue; | ||
438 | else { /* if we _WERE_ tuned, but now don't have a lock */ | ||
439 | fepriv->state = FESTATE_ZIGZAG_FAST; | ||
440 | fepriv->started_auto_step = fepriv->auto_step; | ||
441 | check_wrapped = 0; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | /* don't actually do anything if we're in the LOSTLOCK state, | ||
446 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ | ||
447 | if ((fepriv->state & FESTATE_LOSTLOCK) && | ||
448 | (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { | ||
449 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
450 | continue; | ||
451 | } | ||
452 | |||
453 | /* don't do anything if we're in the DISEQC state, since this | ||
454 | * might be someone with a motorized dish controlled by DISEQC. | ||
455 | * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ | ||
456 | if (fepriv->state & FESTATE_DISEQC) { | ||
457 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
458 | continue; | ||
459 | } | ||
460 | |||
461 | /* if we're in the RETUNE state, set everything up for a brand | ||
462 | * new scan, keeping the current inversion setting, as the next | ||
463 | * tune is _very_ likely to require the same */ | ||
464 | if (fepriv->state & FESTATE_RETUNE) { | ||
465 | fepriv->lnb_drift = 0; | ||
466 | fepriv->auto_step = 0; | ||
467 | fepriv->auto_sub_step = 0; | ||
468 | fepriv->started_auto_step = 0; | ||
469 | check_wrapped = 0; | ||
470 | } | ||
471 | |||
472 | /* fast zigzag. */ | ||
473 | if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { | ||
474 | delay = fepriv->min_delay; | ||
475 | |||
476 | /* peform a tune */ | ||
477 | if (dvb_frontend_autotune(fe, check_wrapped)) { | ||
478 | /* OK, if we've run out of trials at the fast speed. | ||
479 | * Drop back to slow for the _next_ attempt */ | ||
480 | fepriv->state = FESTATE_SEARCHING_SLOW; | ||
481 | fepriv->started_auto_step = fepriv->auto_step; | ||
482 | continue; | ||
483 | } | ||
484 | check_wrapped = 1; | ||
485 | |||
486 | /* if we've just retuned, enter the ZIGZAG_FAST state. | ||
487 | * This ensures we cannot return from an | ||
488 | * FE_SET_FRONTEND ioctl before the first frontend tune | ||
489 | * occurs */ | ||
490 | if (fepriv->state & FESTATE_RETUNE) { | ||
491 | fepriv->state = FESTATE_TUNING_FAST; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | /* slow zigzag */ | ||
496 | if (fepriv->state & FESTATE_SEARCHING_SLOW) { | ||
497 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
498 | |||
499 | /* Note: don't bother checking for wrapping; we stay in this | ||
500 | * state until we get a lock */ | ||
501 | dvb_frontend_autotune(fe, 0); | ||
502 | } | 544 | } |
503 | } | 545 | } |
504 | 546 | ||
@@ -733,7 +775,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
733 | err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); | 775 | err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); |
734 | fepriv->state = FESTATE_DISEQC; | 776 | fepriv->state = FESTATE_DISEQC; |
735 | fepriv->status = 0; | 777 | fepriv->status = 0; |
736 | fepriv->tone = (fe_sec_tone_mode_t) parg; | ||
737 | } | 778 | } |
738 | break; | 779 | break; |
739 | 780 | ||
@@ -747,7 +788,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
747 | 788 | ||
748 | case FE_DISHNETWORK_SEND_LEGACY_CMD: | 789 | case FE_DISHNETWORK_SEND_LEGACY_CMD: |
749 | if (fe->ops->dishnetwork_send_legacy_command) { | 790 | if (fe->ops->dishnetwork_send_legacy_command) { |
750 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); | 791 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); |
751 | fepriv->state = FESTATE_DISEQC; | 792 | fepriv->state = FESTATE_DISEQC; |
752 | fepriv->status = 0; | 793 | fepriv->status = 0; |
753 | } else if (fe->ops->set_voltage) { | 794 | } else if (fe->ops->set_voltage) { |
@@ -767,13 +808,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
767 | * initialization, so parg is 8 bits and does not | 808 | * initialization, so parg is 8 bits and does not |
768 | * include the initialization or start bit | 809 | * include the initialization or start bit |
769 | */ | 810 | */ |
770 | unsigned int cmd = ((unsigned int) parg) << 1; | 811 | unsigned long cmd = ((unsigned long) parg) << 1; |
771 | struct timeval nexttime; | 812 | struct timeval nexttime; |
772 | struct timeval tv[10]; | 813 | struct timeval tv[10]; |
773 | int i; | 814 | int i; |
774 | u8 last = 1; | 815 | u8 last = 1; |
775 | if (dvb_frontend_debug) | 816 | if (dvb_frontend_debug) |
776 | printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd); | 817 | printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd); |
777 | do_gettimeofday(&nexttime); | 818 | do_gettimeofday(&nexttime); |
778 | if (dvb_frontend_debug) | 819 | if (dvb_frontend_debug) |
779 | memcpy(&tv[0], &nexttime, sizeof(struct timeval)); | 820 | memcpy(&tv[0], &nexttime, sizeof(struct timeval)); |
@@ -814,7 +855,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
814 | 855 | ||
815 | case FE_ENABLE_HIGH_LNB_VOLTAGE: | 856 | case FE_ENABLE_HIGH_LNB_VOLTAGE: |
816 | if (fe->ops->enable_high_lnb_voltage) | 857 | if (fe->ops->enable_high_lnb_voltage) |
817 | err = fe->ops->enable_high_lnb_voltage(fe, (int) parg); | 858 | err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); |
818 | break; | 859 | break; |
819 | 860 | ||
820 | case FE_SET_FRONTEND: { | 861 | case FE_SET_FRONTEND: { |
@@ -891,6 +932,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
891 | err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); | 932 | err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); |
892 | } | 933 | } |
893 | break; | 934 | break; |
935 | |||
936 | case FE_SET_FRONTEND_TUNE_MODE: | ||
937 | fepriv->tune_mode_flags = (unsigned long) parg; | ||
938 | break; | ||
894 | }; | 939 | }; |
895 | 940 | ||
896 | up (&fepriv->sem); | 941 | up (&fepriv->sem); |
@@ -932,6 +977,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
932 | 977 | ||
933 | /* empty event queue */ | 978 | /* empty event queue */ |
934 | fepriv->events.eventr = fepriv->events.eventw = 0; | 979 | fepriv->events.eventr = fepriv->events.eventw = 0; |
980 | |||
981 | /* normal tune mode when opened R/W */ | ||
982 | fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; | ||
935 | } | 983 | } |
936 | 984 | ||
937 | return ret; | 985 | return ret; |
@@ -990,7 +1038,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
990 | init_MUTEX (&fepriv->events.sem); | 1038 | init_MUTEX (&fepriv->events.sem); |
991 | fe->dvb = dvb; | 1039 | fe->dvb = dvb; |
992 | fepriv->inversion = INVERSION_OFF; | 1040 | fepriv->inversion = INVERSION_OFF; |
993 | fepriv->tone = SEC_TONE_OFF; | ||
994 | 1041 | ||
995 | printk ("DVB: registering frontend %i (%s)...\n", | 1042 | printk ("DVB: registering frontend %i (%s)...\n", |
996 | fe->dvb->num, | 1043 | fe->dvb->num, |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 1e0840d02f1f..70a6d14efda7 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -58,10 +58,19 @@ struct dvb_frontend_ops { | |||
58 | int (*init)(struct dvb_frontend* fe); | 58 | int (*init)(struct dvb_frontend* fe); |
59 | int (*sleep)(struct dvb_frontend* fe); | 59 | int (*sleep)(struct dvb_frontend* fe); |
60 | 60 | ||
61 | /* if this is set, it overrides the default swzigzag */ | ||
62 | int (*tune)(struct dvb_frontend* fe, | ||
63 | struct dvb_frontend_parameters* params, | ||
64 | unsigned int mode_flags, | ||
65 | int *delay, | ||
66 | fe_status_t *status); | ||
67 | |||
68 | /* these two are only used for the swzigzag code */ | ||
61 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 69 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
62 | int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
63 | int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); | 70 | int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); |
64 | 71 | ||
72 | int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
73 | |||
65 | int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); | 74 | int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); |
66 | int (*read_ber)(struct dvb_frontend* fe, u32* ber); | 75 | int (*read_ber)(struct dvb_frontend* fe, u32* ber); |
67 | int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); | 76 | int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); |
@@ -74,8 +83,9 @@ struct dvb_frontend_ops { | |||
74 | int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); | 83 | int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); |
75 | int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); | 84 | int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); |
76 | int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | 85 | int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); |
77 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg); | 86 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); |
78 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); | 87 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); |
88 | int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); | ||
79 | }; | 89 | }; |
80 | 90 | ||
81 | #define MAX_EVENT 8 | 91 | #define MAX_EVENT 8 |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 86bba81e851e..6711eb6a058c 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -1222,7 +1222,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) | |||
1222 | return if_num; | 1222 | return if_num; |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num) | 1225 | static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) |
1226 | { | 1226 | { |
1227 | struct net_device *net = dvbnet->device[num]; | 1227 | struct net_device *net = dvbnet->device[num]; |
1228 | struct dvb_net_priv *priv; | 1228 | struct dvb_net_priv *priv; |
@@ -1296,9 +1296,9 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1296 | 1296 | ||
1297 | if (!capable(CAP_SYS_ADMIN)) | 1297 | if (!capable(CAP_SYS_ADMIN)) |
1298 | return -EPERM; | 1298 | return -EPERM; |
1299 | if ((unsigned int) parg >= DVB_NET_DEVICES_MAX) | 1299 | if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) |
1300 | return -EINVAL; | 1300 | return -EINVAL; |
1301 | ret = dvb_net_remove_if(dvbnet, (unsigned int) parg); | 1301 | ret = dvb_net_remove_if(dvbnet, (unsigned long) parg); |
1302 | if (!ret) | 1302 | if (!ret) |
1303 | module_put(dvbdev->adapter->module); | 1303 | module_put(dvbdev->adapter->module); |
1304 | return ret; | 1304 | return ret; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 283c6e9339a4..77ad2410f4d3 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c | |||
@@ -112,10 +112,10 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in | |||
112 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; | 112 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; |
113 | if (split > 0) { | 113 | if (split > 0) { |
114 | if (!usermem) | 114 | if (!usermem) |
115 | memcpy(buf, rbuf->data+rbuf->pread, split); | 115 | memcpy(buf, rbuf->data+rbuf->pread, split); |
116 | else | 116 | else |
117 | if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) | 117 | if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) |
118 | return -EFAULT; | 118 | return -EFAULT; |
119 | buf += split; | 119 | buf += split; |
120 | todo -= split; | 120 | todo -= split; |
121 | rbuf->pread = 0; | 121 | rbuf->pread = 0; |
@@ -124,7 +124,7 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in | |||
124 | memcpy(buf, rbuf->data+rbuf->pread, todo); | 124 | memcpy(buf, rbuf->data+rbuf->pread, todo); |
125 | else | 125 | else |
126 | if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) | 126 | if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) |
127 | return -EFAULT; | 127 | return -EFAULT; |
128 | 128 | ||
129 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; | 129 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; |
130 | 130 | ||
@@ -167,7 +167,7 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le | |||
167 | } | 167 | } |
168 | 168 | ||
169 | ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | 169 | ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, |
170 | int offset, u8* buf, size_t len, int usermem) | 170 | int offset, u8* buf, size_t len, int usermem) |
171 | { | 171 | { |
172 | size_t todo; | 172 | size_t todo; |
173 | size_t split; | 173 | size_t split; |
@@ -183,10 +183,10 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | |||
183 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; | 183 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; |
184 | if (split > 0) { | 184 | if (split > 0) { |
185 | if (!usermem) | 185 | if (!usermem) |
186 | memcpy(buf, rbuf->data+idx, split); | 186 | memcpy(buf, rbuf->data+idx, split); |
187 | else | 187 | else |
188 | if (copy_to_user(buf, rbuf->data+idx, split)) | 188 | if (copy_to_user(buf, rbuf->data+idx, split)) |
189 | return -EFAULT; | 189 | return -EFAULT; |
190 | buf += split; | 190 | buf += split; |
191 | todo -= split; | 191 | todo -= split; |
192 | idx = 0; | 192 | idx = 0; |
@@ -195,7 +195,7 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | |||
195 | memcpy(buf, rbuf->data+idx, todo); | 195 | memcpy(buf, rbuf->data+idx, todo); |
196 | else | 196 | else |
197 | if (copy_to_user(buf, rbuf->data+idx, todo)) | 197 | if (copy_to_user(buf, rbuf->data+idx, todo)) |
198 | return -EFAULT; | 198 | return -EFAULT; |
199 | 199 | ||
200 | return len; | 200 | return len; |
201 | } | 201 | } |
@@ -209,12 +209,12 @@ void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx) | |||
209 | // clean up disposed packets | 209 | // clean up disposed packets |
210 | while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { | 210 | while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { |
211 | if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { | 211 | if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { |
212 | pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; | 212 | pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; |
213 | pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); | 213 | pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); |
214 | DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); | 214 | DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); |
215 | } else { | 215 | } else { |
216 | // first packet is not disposed, so we stop cleaning now | 216 | // first packet is not disposed, so we stop cleaning now |
217 | break; | 217 | break; |
218 | } | 218 | } |
219 | } | 219 | } |
220 | } | 220 | } |
@@ -242,8 +242,8 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* | |||
242 | curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; | 242 | curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; |
243 | 243 | ||
244 | if (curpktstatus == PKT_READY) { | 244 | if (curpktstatus == PKT_READY) { |
245 | *pktlen = curpktlen; | 245 | *pktlen = curpktlen; |
246 | return idx; | 246 | return idx; |
247 | } | 247 | } |
248 | 248 | ||
249 | consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; | 249 | consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index fa476f662f82..6d2560972771 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h | |||
@@ -106,7 +106,7 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); | |||
106 | ** returns number of bytes transferred or -EFAULT | 106 | ** returns number of bytes transferred or -EFAULT |
107 | */ | 107 | */ |
108 | extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, | 108 | extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, |
109 | size_t len, int usermem); | 109 | size_t len, int usermem); |
110 | 110 | ||
111 | 111 | ||
112 | /* write routines & macros */ | 112 | /* write routines & macros */ |
@@ -121,7 +121,7 @@ extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, | |||
121 | ** returns number of bytes transferred or -EFAULT | 121 | ** returns number of bytes transferred or -EFAULT |
122 | */ | 122 | */ |
123 | extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, | 123 | extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, |
124 | size_t len); | 124 | size_t len); |
125 | 125 | ||
126 | 126 | ||
127 | /** | 127 | /** |
@@ -133,7 +133,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, | |||
133 | * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. | 133 | * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. |
134 | */ | 134 | */ |
135 | extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, | 135 | extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, |
136 | size_t len); | 136 | size_t len); |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this | 139 | * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this |
@@ -149,7 +149,7 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, | |||
149 | * returns Number of bytes read, or -EFAULT. | 149 | * returns Number of bytes read, or -EFAULT. |
150 | */ | 150 | */ |
151 | extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | 151 | extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, |
152 | int offset, u8* buf, size_t len, int usermem); | 152 | int offset, u8* buf, size_t len, int usermem); |
153 | 153 | ||
154 | /** | 154 | /** |
155 | * Dispose of a packet in the ring buffer. | 155 | * Dispose of a packet in the ring buffer. |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index a4aee8665854..06b696e9acbd 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -92,10 +92,10 @@ static int dvb_device_open(struct inode *inode, struct file *file) | |||
92 | old_fops = file->f_op; | 92 | old_fops = file->f_op; |
93 | file->f_op = fops_get(dvbdev->fops); | 93 | file->f_op = fops_get(dvbdev->fops); |
94 | if(file->f_op->open) | 94 | if(file->f_op->open) |
95 | err = file->f_op->open(inode,file); | 95 | err = file->f_op->open(inode,file); |
96 | if (err) { | 96 | if (err) { |
97 | fops_put(file->f_op); | 97 | fops_put(file->f_op); |
98 | file->f_op = fops_get(old_fops); | 98 | file->f_op = fops_get(old_fops); |
99 | } | 99 | } |
100 | fops_put(old_fops); | 100 | fops_put(old_fops); |
101 | return err; | 101 | return err; |
@@ -356,18 +356,18 @@ int dvb_usercopy(struct inode *inode, struct file *file, | |||
356 | case _IOC_WRITE: | 356 | case _IOC_WRITE: |
357 | case (_IOC_WRITE | _IOC_READ): | 357 | case (_IOC_WRITE | _IOC_READ): |
358 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { | 358 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { |
359 | parg = sbuf; | 359 | parg = sbuf; |
360 | } else { | 360 | } else { |
361 | /* too big to allocate from stack */ | 361 | /* too big to allocate from stack */ |
362 | mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); | 362 | mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); |
363 | if (NULL == mbuf) | 363 | if (NULL == mbuf) |
364 | return -ENOMEM; | 364 | return -ENOMEM; |
365 | parg = mbuf; | 365 | parg = mbuf; |
366 | } | 366 | } |
367 | 367 | ||
368 | err = -EFAULT; | 368 | err = -EFAULT; |
369 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | 369 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) |
370 | goto out; | 370 | goto out; |
371 | break; | 371 | break; |
372 | } | 372 | } |
373 | 373 | ||
@@ -384,7 +384,7 @@ int dvb_usercopy(struct inode *inode, struct file *file, | |||
384 | case _IOC_READ: | 384 | case _IOC_READ: |
385 | case (_IOC_WRITE | _IOC_READ): | 385 | case (_IOC_WRITE | _IOC_READ): |
386 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | 386 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) |
387 | err = -EFAULT; | 387 | err = -EFAULT; |
388 | break; | 388 | break; |
389 | } | 389 | } |
390 | 390 | ||
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 0cc6e4a0e27c..74ed5853f0fb 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -97,7 +97,7 @@ we simply define out own dvb_usercopy(), which will hopefully become | |||
97 | generic_usercopy() someday... */ | 97 | generic_usercopy() someday... */ |
98 | 98 | ||
99 | extern int dvb_usercopy(struct inode *inode, struct file *file, | 99 | extern int dvb_usercopy(struct inode *inode, struct file *file, |
100 | unsigned int cmd, unsigned long arg, | 100 | unsigned int cmd, unsigned long arg, |
101 | int (*func)(struct inode *inode, struct file *file, | 101 | int (*func)(struct inode *inode, struct file *file, |
102 | unsigned int cmd, void *arg)); | 102 | unsigned int cmd, void *arg)); |
103 | 103 | ||
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 54e2b29076b1..90a69d343b79 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -37,16 +37,16 @@ config DVB_USB_DIBUSB_MB | |||
37 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. | 37 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. |
38 | 38 | ||
39 | Devices supported by this driver: | 39 | Devices supported by this driver: |
40 | TwinhanDTV USB-Ter (VP7041) | 40 | Artec T1 USB1.1 boxes |
41 | TwinhanDTV Magic Box (VP7041e) | 41 | Avermedia AverTV DVBT USB1.1 |
42 | KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 | ||
43 | Hama DVB-T USB1.1-Box | ||
44 | DiBcom USB1.1 reference devices (non-public) | ||
45 | Ultima Electronic/Artec T1 USB TVBOX | ||
46 | Compro Videomate DVB-U2000 - DVB-T USB | 42 | Compro Videomate DVB-U2000 - DVB-T USB |
43 | DiBcom USB1.1 reference devices (non-public) | ||
47 | Grandtec DVB-T USB | 44 | Grandtec DVB-T USB |
48 | Avermedia AverTV DVBT USB1.1 | 45 | Hama DVB-T USB1.1-Box |
49 | Artec T1 USB1.1 boxes | 46 | KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 |
47 | TwinhanDTV Magic Box (VP7041e) | ||
48 | TwinhanDTV USB-Ter (VP7041) | ||
49 | Ultima Electronic/Artec T1 USB TVBOX | ||
50 | 50 | ||
51 | The VP7041 seems to be identical to "CTS Portable" (Chinese | 51 | The VP7041 seems to be identical to "CTS Portable" (Chinese |
52 | Television System). | 52 | Television System). |
@@ -54,6 +54,12 @@ config DVB_USB_DIBUSB_MB | |||
54 | Say Y if you own such a device and want to use it. You should build it as | 54 | Say Y if you own such a device and want to use it. You should build it as |
55 | a module. | 55 | a module. |
56 | 56 | ||
57 | config DVB_USB_DIBUSB_MB_FAULTY | ||
58 | bool "Support faulty USB IDs" | ||
59 | depends on DVB_USB_DIBUSB_MB | ||
60 | help | ||
61 | Support for faulty USB IDs due to an invalid EEPROM on some Artec devices. | ||
62 | |||
57 | config DVB_USB_DIBUSB_MC | 63 | config DVB_USB_DIBUSB_MC |
58 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" | 64 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" |
59 | depends on DVB_USB | 65 | depends on DVB_USB |
@@ -63,8 +69,8 @@ config DVB_USB_DIBUSB_MC | |||
63 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. | 69 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. |
64 | 70 | ||
65 | Devices supported by this driver: | 71 | Devices supported by this driver: |
66 | DiBcom USB2.0 reference devices (non-public) | ||
67 | Artec T1 USB2.0 boxes | 72 | Artec T1 USB2.0 boxes |
73 | DiBcom USB2.0 reference devices (non-public) | ||
68 | 74 | ||
69 | Say Y if you own such a device and want to use it. You should build it as | 75 | Say Y if you own such a device and want to use it. You should build it as |
70 | a module. | 76 | a module. |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index d05fab01cccd..358ed153865f 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -11,10 +11,11 @@ | |||
11 | * design, so it can be reused for the "analogue-only" device (if it will | 11 | * design, so it can be reused for the "analogue-only" device (if it will |
12 | * appear at all). | 12 | * appear at all). |
13 | * | 13 | * |
14 | * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue | 14 | * TODO: Use the cx25840-driver for the analogue part |
15 | * part | ||
16 | * | 15 | * |
17 | * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) | 16 | * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) |
17 | * Copyright (C) 2005 Michael Krufky (mkrufky@m1k.net) | ||
18 | * Copyright (C) 2006 Chris Pascoe (c.pascoe@itee.uq.edu.au) | ||
18 | * | 19 | * |
19 | * This program is free software; you can redistribute it and/or modify it | 20 | * This program is free software; you can redistribute it and/or modify it |
20 | * under the terms of the GNU General Public License as published by the Free | 21 | * under the terms of the GNU General Public License as published by the Free |
@@ -25,6 +26,9 @@ | |||
25 | #include "cxusb.h" | 26 | #include "cxusb.h" |
26 | 27 | ||
27 | #include "cx22702.h" | 28 | #include "cx22702.h" |
29 | #include "lgdt330x.h" | ||
30 | #include "mt352.h" | ||
31 | #include "mt352_priv.h" | ||
28 | 32 | ||
29 | /* debug */ | 33 | /* debug */ |
30 | int dvb_usb_cxusb_debug; | 34 | int dvb_usb_cxusb_debug; |
@@ -156,6 +160,99 @@ static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) | |||
156 | return 0; | 160 | return 0; |
157 | } | 161 | } |
158 | 162 | ||
163 | static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||
164 | { | ||
165 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; | ||
166 | u8 ircode[4]; | ||
167 | int i; | ||
168 | |||
169 | cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); | ||
170 | |||
171 | *event = 0; | ||
172 | *state = REMOTE_NO_KEY_PRESSED; | ||
173 | |||
174 | for (i = 0; i < d->props.rc_key_map_size; i++) { | ||
175 | if (keymap[i].custom == ircode[2] && | ||
176 | keymap[i].data == ircode[3]) { | ||
177 | *event = keymap[i].event; | ||
178 | *state = REMOTE_KEY_PRESSED; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | ||
188 | { 0xfe, 0x02, KEY_TV }, | ||
189 | { 0xfe, 0x0e, KEY_MP3 }, | ||
190 | { 0xfe, 0x1a, KEY_DVD }, | ||
191 | { 0xfe, 0x1e, KEY_FAVORITES }, | ||
192 | { 0xfe, 0x16, KEY_SETUP }, | ||
193 | { 0xfe, 0x46, KEY_POWER2 }, | ||
194 | { 0xfe, 0x0a, KEY_EPG }, | ||
195 | { 0xfe, 0x49, KEY_BACK }, | ||
196 | { 0xfe, 0x4d, KEY_MENU }, | ||
197 | { 0xfe, 0x51, KEY_UP }, | ||
198 | { 0xfe, 0x5b, KEY_LEFT }, | ||
199 | { 0xfe, 0x5f, KEY_RIGHT }, | ||
200 | { 0xfe, 0x53, KEY_DOWN }, | ||
201 | { 0xfe, 0x5e, KEY_OK }, | ||
202 | { 0xfe, 0x59, KEY_INFO }, | ||
203 | { 0xfe, 0x55, KEY_TAB }, | ||
204 | { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */ | ||
205 | { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */ | ||
206 | { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */ | ||
207 | { 0xfe, 0x15, KEY_VOLUMEUP }, | ||
208 | { 0xfe, 0x05, KEY_VOLUMEDOWN }, | ||
209 | { 0xfe, 0x11, KEY_CHANNELUP }, | ||
210 | { 0xfe, 0x09, KEY_CHANNELDOWN }, | ||
211 | { 0xfe, 0x52, KEY_CAMERA }, | ||
212 | { 0xfe, 0x5a, KEY_TUNER }, /* Live */ | ||
213 | { 0xfe, 0x19, KEY_OPEN }, | ||
214 | { 0xfe, 0x0b, KEY_1 }, | ||
215 | { 0xfe, 0x17, KEY_2 }, | ||
216 | { 0xfe, 0x1b, KEY_3 }, | ||
217 | { 0xfe, 0x07, KEY_4 }, | ||
218 | { 0xfe, 0x50, KEY_5 }, | ||
219 | { 0xfe, 0x54, KEY_6 }, | ||
220 | { 0xfe, 0x48, KEY_7 }, | ||
221 | { 0xfe, 0x4c, KEY_8 }, | ||
222 | { 0xfe, 0x58, KEY_9 }, | ||
223 | { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */ | ||
224 | { 0xfe, 0x03, KEY_0 }, | ||
225 | { 0xfe, 0x1f, KEY_ZOOM }, | ||
226 | { 0xfe, 0x43, KEY_REWIND }, | ||
227 | { 0xfe, 0x47, KEY_PLAYPAUSE }, | ||
228 | { 0xfe, 0x4f, KEY_FASTFORWARD }, | ||
229 | { 0xfe, 0x57, KEY_MUTE }, | ||
230 | { 0xfe, 0x0d, KEY_STOP }, | ||
231 | { 0xfe, 0x01, KEY_RECORD }, | ||
232 | { 0xfe, 0x4e, KEY_POWER }, | ||
233 | }; | ||
234 | |||
235 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | ||
236 | { | ||
237 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | ||
238 | static u8 reset [] = { RESET, 0x80 }; | ||
239 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | ||
240 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | ||
241 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | ||
242 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
243 | |||
244 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
245 | udelay(200); | ||
246 | mt352_write(fe, reset, sizeof(reset)); | ||
247 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
248 | |||
249 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
250 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | ||
251 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
159 | struct cx22702_config cxusb_cx22702_config = { | 256 | struct cx22702_config cxusb_cx22702_config = { |
160 | .demod_address = 0x63, | 257 | .demod_address = 0x63, |
161 | 258 | ||
@@ -165,17 +262,47 @@ struct cx22702_config cxusb_cx22702_config = { | |||
165 | .pll_set = dvb_usb_pll_set_i2c, | 262 | .pll_set = dvb_usb_pll_set_i2c, |
166 | }; | 263 | }; |
167 | 264 | ||
265 | struct lgdt330x_config cxusb_lgdt330x_config = { | ||
266 | .demod_address = 0x0e, | ||
267 | .demod_chip = LGDT3303, | ||
268 | .pll_set = dvb_usb_pll_set_i2c, | ||
269 | }; | ||
270 | |||
271 | struct mt352_config cxusb_dee1601_config = { | ||
272 | .demod_address = 0x0f, | ||
273 | .demod_init = cxusb_dee1601_demod_init, | ||
274 | .pll_set = dvb_usb_pll_set, | ||
275 | }; | ||
276 | |||
168 | /* Callbacks for DVB USB */ | 277 | /* Callbacks for DVB USB */ |
169 | static int cxusb_tuner_attach(struct dvb_usb_device *d) | 278 | static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d) |
170 | { | 279 | { |
171 | u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | 280 | u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; |
172 | d->pll_addr = 0x61; | 281 | d->pll_addr = 0x61; |
173 | memcpy(d->pll_init,bpll,4); | 282 | memcpy(d->pll_init, bpll, 4); |
174 | d->pll_desc = &dvb_pll_fmd1216me; | 283 | d->pll_desc = &dvb_pll_fmd1216me; |
175 | return 0; | 284 | return 0; |
176 | } | 285 | } |
177 | 286 | ||
178 | static int cxusb_frontend_attach(struct dvb_usb_device *d) | 287 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) |
288 | { | ||
289 | u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; | ||
290 | /* bpll[2] : unset bit 3, set bits 4&5 | ||
291 | bpll[3] : 0x50 - digital, 0x20 - analog */ | ||
292 | d->pll_addr = 0x61; | ||
293 | memcpy(d->pll_init, bpll, 4); | ||
294 | d->pll_desc = &dvb_pll_tdvs_tua6034; | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d) | ||
299 | { | ||
300 | d->pll_addr = 0x61; | ||
301 | d->pll_desc = &dvb_pll_thomson_dtt7579; | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) | ||
179 | { | 306 | { |
180 | u8 b; | 307 | u8 b; |
181 | if (usb_set_interface(d->udev,0,6) < 0) | 308 | if (usb_set_interface(d->udev,0,6) < 0) |
@@ -189,22 +316,84 @@ static int cxusb_frontend_attach(struct dvb_usb_device *d) | |||
189 | return -EIO; | 316 | return -EIO; |
190 | } | 317 | } |
191 | 318 | ||
319 | static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d) | ||
320 | { | ||
321 | if (usb_set_interface(d->udev,0,7) < 0) | ||
322 | err("set interface failed"); | ||
323 | |||
324 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | ||
325 | |||
326 | if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL) | ||
327 | return 0; | ||
328 | |||
329 | return -EIO; | ||
330 | } | ||
331 | |||
332 | static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) | ||
333 | { | ||
334 | if (usb_set_interface(d->udev,0,0) < 0) | ||
335 | err("set interface failed"); | ||
336 | |||
337 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | ||
338 | |||
339 | if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) | ||
340 | return 0; | ||
341 | |||
342 | return -EIO; | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * DViCO bluebird firmware needs the "warm" product ID to be patched into the | ||
347 | * firmware file before download. | ||
348 | */ | ||
349 | |||
350 | #define BLUEBIRD_01_ID_OFFSET 6638 | ||
351 | static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const struct firmware *fw) | ||
352 | { | ||
353 | if (fw->size < BLUEBIRD_01_ID_OFFSET + 4) | ||
354 | return -EINVAL; | ||
355 | |||
356 | if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) && | ||
357 | fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) { | ||
358 | |||
359 | /* FIXME: are we allowed to change the fw-data ? */ | ||
360 | fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1; | ||
361 | fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8; | ||
362 | |||
363 | return usb_cypress_load_firmware(udev,fw,CYPRESS_FX2); | ||
364 | } | ||
365 | |||
366 | return -EINVAL; | ||
367 | } | ||
368 | |||
192 | /* DVB USB Driver stuff */ | 369 | /* DVB USB Driver stuff */ |
193 | static struct dvb_usb_properties cxusb_properties; | 370 | static struct dvb_usb_properties cxusb_medion_properties; |
371 | static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties; | ||
372 | static struct dvb_usb_properties cxusb_bluebird_dee1601_properties; | ||
194 | 373 | ||
195 | static int cxusb_probe(struct usb_interface *intf, | 374 | static int cxusb_probe(struct usb_interface *intf, |
196 | const struct usb_device_id *id) | 375 | const struct usb_device_id *id) |
197 | { | 376 | { |
198 | return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL); | 377 | if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 || |
378 | dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 || | ||
379 | dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0) { | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | return -EINVAL; | ||
199 | } | 384 | } |
200 | 385 | ||
201 | static struct usb_device_id cxusb_table [] = { | 386 | static struct usb_device_id cxusb_table [] = { |
202 | { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, | 387 | { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, |
388 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, | ||
389 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) }, | ||
390 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) }, | ||
391 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) }, | ||
203 | {} /* Terminating entry */ | 392 | {} /* Terminating entry */ |
204 | }; | 393 | }; |
205 | MODULE_DEVICE_TABLE (usb, cxusb_table); | 394 | MODULE_DEVICE_TABLE (usb, cxusb_table); |
206 | 395 | ||
207 | static struct dvb_usb_properties cxusb_properties = { | 396 | static struct dvb_usb_properties cxusb_medion_properties = { |
208 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 397 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
209 | 398 | ||
210 | .usb_ctrl = CYPRESS_FX2, | 399 | .usb_ctrl = CYPRESS_FX2, |
@@ -213,8 +402,8 @@ static struct dvb_usb_properties cxusb_properties = { | |||
213 | 402 | ||
214 | .streaming_ctrl = cxusb_streaming_ctrl, | 403 | .streaming_ctrl = cxusb_streaming_ctrl, |
215 | .power_ctrl = cxusb_power_ctrl, | 404 | .power_ctrl = cxusb_power_ctrl, |
216 | .frontend_attach = cxusb_frontend_attach, | 405 | .frontend_attach = cxusb_cx22702_frontend_attach, |
217 | .tuner_attach = cxusb_tuner_attach, | 406 | .tuner_attach = cxusb_fmd1216me_tuner_attach, |
218 | 407 | ||
219 | .i2c_algo = &cxusb_i2c_algo, | 408 | .i2c_algo = &cxusb_i2c_algo, |
220 | 409 | ||
@@ -240,6 +429,91 @@ static struct dvb_usb_properties cxusb_properties = { | |||
240 | } | 429 | } |
241 | }; | 430 | }; |
242 | 431 | ||
432 | static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { | ||
433 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
434 | |||
435 | .usb_ctrl = DEVICE_SPECIFIC, | ||
436 | .firmware = "dvb-usb-bluebird-01.fw", | ||
437 | .download_firmware = bluebird_patch_dvico_firmware_download, | ||
438 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | ||
439 | use usb alt setting 7 for EP2 transfer (atsc) */ | ||
440 | |||
441 | .size_of_priv = sizeof(struct cxusb_state), | ||
442 | |||
443 | .streaming_ctrl = cxusb_streaming_ctrl, | ||
444 | .power_ctrl = cxusb_power_ctrl, | ||
445 | .frontend_attach = cxusb_lgdt330x_frontend_attach, | ||
446 | .tuner_attach = cxusb_lgh064f_tuner_attach, | ||
447 | |||
448 | .i2c_algo = &cxusb_i2c_algo, | ||
449 | |||
450 | .generic_bulk_ctrl_endpoint = 0x01, | ||
451 | /* parameter for the MPEG2-data transfer */ | ||
452 | .urb = { | ||
453 | .type = DVB_USB_BULK, | ||
454 | .count = 5, | ||
455 | .endpoint = 0x02, | ||
456 | .u = { | ||
457 | .bulk = { | ||
458 | .buffersize = 8192, | ||
459 | } | ||
460 | } | ||
461 | }, | ||
462 | |||
463 | .num_device_descs = 1, | ||
464 | .devices = { | ||
465 | { "DViCO FusionHDTV5 USB Gold", | ||
466 | { &cxusb_table[1], NULL }, | ||
467 | { &cxusb_table[2], NULL }, | ||
468 | }, | ||
469 | } | ||
470 | }; | ||
471 | |||
472 | static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = { | ||
473 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
474 | |||
475 | .usb_ctrl = DEVICE_SPECIFIC, | ||
476 | .firmware = "dvb-usb-bluebird-01.fw", | ||
477 | .download_firmware = bluebird_patch_dvico_firmware_download, | ||
478 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | ||
479 | use usb alt setting 7 for EP2 transfer (atsc) */ | ||
480 | |||
481 | .size_of_priv = sizeof(struct cxusb_state), | ||
482 | |||
483 | .streaming_ctrl = cxusb_streaming_ctrl, | ||
484 | .power_ctrl = cxusb_power_ctrl, | ||
485 | .frontend_attach = cxusb_dee1601_frontend_attach, | ||
486 | .tuner_attach = cxusb_dee1601_tuner_attach, | ||
487 | |||
488 | .i2c_algo = &cxusb_i2c_algo, | ||
489 | |||
490 | .rc_interval = 150, | ||
491 | .rc_key_map = dvico_mce_rc_keys, | ||
492 | .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), | ||
493 | .rc_query = cxusb_rc_query, | ||
494 | |||
495 | .generic_bulk_ctrl_endpoint = 0x01, | ||
496 | /* parameter for the MPEG2-data transfer */ | ||
497 | .urb = { | ||
498 | .type = DVB_USB_BULK, | ||
499 | .count = 5, | ||
500 | .endpoint = 0x04, | ||
501 | .u = { | ||
502 | .bulk = { | ||
503 | .buffersize = 8192, | ||
504 | } | ||
505 | } | ||
506 | }, | ||
507 | |||
508 | .num_device_descs = 1, | ||
509 | .devices = { | ||
510 | { "DViCO FusionHDTV DVB-T Dual USB", | ||
511 | { &cxusb_table[3], NULL }, | ||
512 | { &cxusb_table[4], NULL }, | ||
513 | }, | ||
514 | } | ||
515 | }; | ||
516 | |||
243 | static struct usb_driver cxusb_driver = { | 517 | static struct usb_driver cxusb_driver = { |
244 | .name = "dvb_usb_cxusb", | 518 | .name = "dvb_usb_cxusb", |
245 | .probe = cxusb_probe, | 519 | .probe = cxusb_probe, |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h index 135c2a81f581..087c99427853 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.h +++ b/drivers/media/dvb/dvb-usb/cxusb.h | |||
@@ -21,6 +21,8 @@ extern int dvb_usb_cxusb_debug; | |||
21 | #define CMD_STREAMING_ON 0x36 | 21 | #define CMD_STREAMING_ON 0x36 |
22 | #define CMD_STREAMING_OFF 0x37 | 22 | #define CMD_STREAMING_OFF 0x37 |
23 | 23 | ||
24 | #define CMD_GET_IR_CODE 0x47 | ||
25 | |||
24 | #define CMD_ANALOG 0x50 | 26 | #define CMD_ANALOG 0x50 |
25 | #define CMD_DIGITAL 0x51 | 27 | #define CMD_DIGITAL 0x51 |
26 | 28 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 52ac3e5adf5d..dd5a13195886 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -65,11 +65,11 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d) | |||
65 | d->tuner_pass_ctrl(d->fe,0,msg[0].addr); | 65 | d->tuner_pass_ctrl(d->fe,0,msg[0].addr); |
66 | 66 | ||
67 | if (b2[0] == 0xfe) { | 67 | if (b2[0] == 0xfe) { |
68 | info("this device has the Thomson Cable onboard. Which is default."); | 68 | info("This device has the Thomson Cable onboard. Which is default."); |
69 | dibusb_thomson_tuner_attach(d); | 69 | dibusb_thomson_tuner_attach(d); |
70 | } else { | 70 | } else { |
71 | u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; | 71 | u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; |
72 | info("this device has the Panasonic ENV77H11D5 onboard."); | 72 | info("This device has the Panasonic ENV77H11D5 onboard."); |
73 | d->pll_addr = 0x60; | 73 | d->pll_addr = 0x60; |
74 | memcpy(d->pll_init,bpll,4); | 74 | memcpy(d->pll_init,bpll,4); |
75 | d->pll_desc = &dvb_pll_tda665x; | 75 | d->pll_desc = &dvb_pll_tda665x; |
@@ -98,15 +98,15 @@ static int dibusb_probe(struct usb_interface *intf, | |||
98 | 98 | ||
99 | /* do not change the order of the ID table */ | 99 | /* do not change the order of the ID table */ |
100 | static struct usb_device_id dibusb_dib3000mb_table [] = { | 100 | static struct usb_device_id dibusb_dib3000mb_table [] = { |
101 | /* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, | 101 | /* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) }, |
102 | /* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, | 102 | /* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) }, |
103 | /* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, | 103 | /* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, |
104 | /* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, | 104 | /* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, |
105 | /* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, | 105 | /* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, |
106 | /* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, | 106 | /* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, |
107 | /* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, | 107 | /* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, |
108 | /* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, | 108 | /* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, |
109 | /* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, | 109 | /* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, |
110 | /* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, | 110 | /* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, |
111 | /* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, | 111 | /* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, |
112 | /* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, | 112 | /* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, |
@@ -117,27 +117,34 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { | |||
117 | /* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, | 117 | /* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, |
118 | /* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, | 118 | /* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, |
119 | /* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, | 119 | /* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, |
120 | /* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, | 120 | /* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, |
121 | /* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, | 121 | /* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, |
122 | /* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, | 122 | /* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, |
123 | /* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, | 123 | /* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, |
124 | /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, | 124 | /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, |
125 | 125 | ||
126 | /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ | 126 | /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ |
127 | /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, | 127 | /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, |
128 | /* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, | 128 | /* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, |
129 | /* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, | 129 | /* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, |
130 | 130 | ||
131 | /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, | 131 | /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, |
132 | 132 | ||
133 | /* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, | 133 | /* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, |
134 | /* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, | 134 | /* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, |
135 | 135 | ||
136 | // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 136 | /* |
137 | * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices | ||
138 | * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that | ||
139 | * have been left on the device. If you don't have such a device but an Artec | ||
140 | * device that's supposed to work with this driver but is not detected by it, | ||
141 | * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config. | ||
142 | */ | ||
137 | 143 | ||
138 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 144 | #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY |
139 | /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, | 145 | /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, |
140 | #endif | 146 | #endif |
147 | |||
141 | { } /* Terminating entry */ | 148 | { } /* Terminating entry */ |
142 | }; | 149 | }; |
143 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); | 150 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); |
@@ -257,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { | |||
257 | } | 264 | } |
258 | }, | 265 | }, |
259 | 266 | ||
260 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 267 | #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY |
261 | .num_device_descs = 2, | 268 | .num_device_descs = 2, |
262 | #else | 269 | #else |
263 | .num_device_descs = 1, | 270 | .num_device_descs = 1, |
@@ -267,11 +274,12 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { | |||
267 | { &dibusb_dib3000mb_table[20], NULL }, | 274 | { &dibusb_dib3000mb_table[20], NULL }, |
268 | { &dibusb_dib3000mb_table[21], NULL }, | 275 | { &dibusb_dib3000mb_table[21], NULL }, |
269 | }, | 276 | }, |
270 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 277 | #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY |
271 | { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", | 278 | { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", |
272 | { &dibusb_dib3000mb_table[30], NULL }, | 279 | { &dibusb_dib3000mb_table[30], NULL }, |
273 | { NULL }, | 280 | { NULL }, |
274 | }, | 281 | }, |
282 | { NULL }, | ||
275 | #endif | 283 | #endif |
276 | } | 284 | } |
277 | }; | 285 | }; |
@@ -323,6 +331,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = { | |||
323 | { &dibusb_dib3000mb_table[27], NULL }, | 331 | { &dibusb_dib3000mb_table[27], NULL }, |
324 | { NULL } | 332 | { NULL } |
325 | }, | 333 | }, |
334 | { NULL }, | ||
326 | } | 335 | } |
327 | }; | 336 | }; |
328 | 337 | ||
@@ -369,6 +378,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = { | |||
369 | { &dibusb_dib3000mb_table[28], NULL }, | 378 | { &dibusb_dib3000mb_table[28], NULL }, |
370 | { &dibusb_dib3000mb_table[29], NULL }, | 379 | { &dibusb_dib3000mb_table[29], NULL }, |
371 | }, | 380 | }, |
381 | { NULL }, | ||
372 | } | 382 | } |
373 | }; | 383 | }; |
374 | 384 | ||
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 450417a9e64b..e6c55c9c9417 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -32,7 +32,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d, | |||
32 | sndbuf[1] = vv; | 32 | sndbuf[1] = vv; |
33 | sndbuf[2] = wo ? wlen : rlen; | 33 | sndbuf[2] = wo ? wlen : rlen; |
34 | 34 | ||
35 | if (!wo) { | 35 | if (wo) { |
36 | memcpy(&sndbuf[3],wbuf,wlen); | 36 | memcpy(&sndbuf[3],wbuf,wlen); |
37 | dvb_usb_generic_write(d,sndbuf,7); | 37 | dvb_usb_generic_write(d,sndbuf,7); |
38 | } else { | 38 | } else { |
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 6e2bac873445..130ea7f21f5e 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { | |||
151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, | 151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, |
152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, | 152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, |
153 | }, | 153 | }, |
154 | { NULL }, | 154 | { 0 }, |
155 | } | 155 | } |
156 | }; | 156 | }; |
157 | 157 | ||
@@ -160,7 +160,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
160 | .pid_filter_count = 15, | 160 | .pid_filter_count = 15, |
161 | 161 | ||
162 | .usb_ctrl = CYPRESS_FX2, | 162 | .usb_ctrl = CYPRESS_FX2, |
163 | .firmware = "dvb-usb-wt220u-01.fw", | 163 | .firmware = "dvb-usb-wt220u-02.fw", |
164 | 164 | ||
165 | .power_ctrl = dtt200u_power_ctrl, | 165 | .power_ctrl = dtt200u_power_ctrl, |
166 | .streaming_ctrl = dtt200u_streaming_ctrl, | 166 | .streaming_ctrl = dtt200u_streaming_ctrl, |
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, | 192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, |
193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, | 193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, |
194 | }, | 194 | }, |
195 | { NULL }, | 195 | { 0 }, |
196 | } | 196 | } |
197 | }; | 197 | }; |
198 | 198 | ||
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h index 6f1f3042e21a..005b0a7df358 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.h +++ b/drivers/media/dvb/dvb-usb/dtt200u.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define _DVB_USB_DTT200U_H_ | 13 | #define _DVB_USB_DTT200U_H_ |
14 | 14 | ||
15 | #define DVB_USB_LOG_PREFIX "dtt200u" | 15 | #define DVB_USB_LOG_PREFIX "dtt200u" |
16 | |||
16 | #include "dvb-usb.h" | 17 | #include "dvb-usb.h" |
17 | 18 | ||
18 | extern int dvb_usb_dtt200u_debug; | 19 | extern int dvb_usb_dtt200u_debug; |
@@ -25,15 +26,15 @@ extern int dvb_usb_dtt200u_debug; | |||
25 | * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) | 26 | * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) |
26 | */ | 27 | */ |
27 | 28 | ||
28 | #define GET_SPEED 0x00 | 29 | #define GET_SPEED 0x00 |
29 | #define GET_TUNE_STATUS 0x81 | 30 | #define GET_TUNE_STATUS 0x81 |
30 | #define GET_RC_CODE 0x84 | 31 | #define GET_RC_CODE 0x84 |
31 | #define GET_CONFIGURATION 0x88 | 32 | #define GET_CONFIGURATION 0x88 |
32 | #define GET_AGC 0x89 | 33 | #define GET_AGC 0x89 |
33 | #define GET_SNR 0x8a | 34 | #define GET_SNR 0x8a |
34 | #define GET_VIT_ERR_CNT 0x8c | 35 | #define GET_VIT_ERR_CNT 0x8c |
35 | #define GET_RS_ERR_CNT 0x8d | 36 | #define GET_RS_ERR_CNT 0x8d |
36 | #define GET_RS_UNCOR_BLK_CNT 0x8e | 37 | #define GET_RS_UNCOR_BLK_CNT 0x8e |
37 | 38 | ||
38 | /* write | 39 | /* write |
39 | * 01 - init | 40 | * 01 - init |
@@ -44,12 +45,12 @@ extern int dvb_usb_dtt200u_debug; | |||
44 | * 08 - transfer switch | 45 | * 08 - transfer switch |
45 | */ | 46 | */ |
46 | 47 | ||
47 | #define SET_INIT 0x01 | 48 | #define SET_INIT 0x01 |
48 | #define SET_RF_FREQ 0x02 | 49 | #define SET_RF_FREQ 0x02 |
49 | #define SET_BANDWIDTH 0x03 | 50 | #define SET_BANDWIDTH 0x03 |
50 | #define SET_PID_FILTER 0x04 | 51 | #define SET_PID_FILTER 0x04 |
51 | #define RESET_PID_FILTER 0x05 | 52 | #define RESET_PID_FILTER 0x05 |
52 | #define SET_STREAMING 0x08 | 53 | #define SET_STREAMING 0x08 |
53 | 54 | ||
54 | extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); | 55 | extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); |
55 | 56 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h index 7300489d3e24..a3460bf2d9fa 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h | |||
@@ -24,7 +24,7 @@ extern int dvb_usb_disable_rc_polling; | |||
24 | #define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) | 24 | #define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) |
25 | 25 | ||
26 | /* commonly used methods */ | 26 | /* commonly used methods */ |
27 | extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); | 27 | extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *); |
28 | 28 | ||
29 | extern int dvb_usb_urb_submit(struct dvb_usb_device *); | 29 | extern int dvb_usb_urb_submit(struct dvb_usb_device *); |
30 | extern int dvb_usb_urb_kill(struct dvb_usb_device *); | 30 | extern int dvb_usb_urb_kill(struct dvb_usb_device *); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index 5244e39770a0..8535895819fb 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | #include "dvb-usb-common.h" | 10 | #include "dvb-usb-common.h" |
11 | 11 | ||
12 | #include <linux/firmware.h> | ||
13 | #include <linux/usb.h> | 12 | #include <linux/usb.h> |
14 | 13 | ||
15 | struct usb_cypress_controller { | 14 | struct usb_cypress_controller { |
@@ -19,9 +18,10 @@ struct usb_cypress_controller { | |||
19 | }; | 18 | }; |
20 | 19 | ||
21 | static struct usb_cypress_controller cypress[] = { | 20 | static struct usb_cypress_controller cypress[] = { |
22 | { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, | 21 | { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 }, |
23 | { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, | 22 | { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, |
24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, | 23 | { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, |
24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, | ||
25 | }; | 25 | }; |
26 | 26 | ||
27 | /* | 27 | /* |
@@ -30,71 +30,117 @@ static struct usb_cypress_controller cypress[] = { | |||
30 | static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) | 30 | static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) |
31 | { | 31 | { |
32 | return usb_control_msg(udev, usb_sndctrlpipe(udev,0), | 32 | return usb_control_msg(udev, usb_sndctrlpipe(udev,0), |
33 | 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); | 33 | 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000); |
34 | } | 34 | } |
35 | 35 | ||
36 | int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type) | 36 | int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) |
37 | { | 37 | { |
38 | const struct firmware *fw = NULL; | 38 | struct hexline hx; |
39 | u16 addr; | 39 | u8 reset; |
40 | u8 *b,*p; | 40 | int ret,pos=0; |
41 | int ret = 0,i; | ||
42 | 41 | ||
43 | if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) { | 42 | /* stop the CPU */ |
44 | err("did not find the firmware file. (%s) " | 43 | reset = 1; |
45 | "Please see linux/Documentation/dvb/ for more details on firmware-problems.", | 44 | if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) |
46 | filename); | 45 | err("could not stop the USB controller CPU."); |
46 | |||
47 | while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { | ||
48 | deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); | ||
49 | ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); | ||
50 | |||
51 | if (ret != hx.len) { | ||
52 | err("error while transferring firmware " | ||
53 | "(transferred size: %d, block size: %d)", | ||
54 | ret,hx.len); | ||
55 | ret = -EINVAL; | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | if (ret < 0) { | ||
60 | err("firmware download failed at %d with %d",pos,ret); | ||
47 | return ret; | 61 | return ret; |
48 | } | 62 | } |
49 | 63 | ||
50 | info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name); | 64 | if (ret == 0) { |
51 | |||
52 | p = kmalloc(fw->size,GFP_KERNEL); | ||
53 | if (p != NULL) { | ||
54 | u8 reset; | ||
55 | /* | ||
56 | * you cannot use the fw->data as buffer for | ||
57 | * usb_control_msg, a new buffer has to be | ||
58 | * created | ||
59 | */ | ||
60 | memcpy(p,fw->data,fw->size); | ||
61 | |||
62 | /* stop the CPU */ | ||
63 | reset = 1; | ||
64 | if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) | ||
65 | err("could not stop the USB controller CPU."); | ||
66 | for(i = 0; p[i+3] == 0 && i < fw->size; ) { | ||
67 | b = (u8 *) &p[i]; | ||
68 | addr = cpu_to_le16( *((u16 *) &b[1]) ); | ||
69 | |||
70 | deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]); | ||
71 | |||
72 | ret = usb_cypress_writemem(udev,addr,&b[4],b[0]); | ||
73 | |||
74 | if (ret != b[0]) { | ||
75 | err("error while transferring firmware " | ||
76 | "(transferred size: %d, block size: %d)", | ||
77 | ret,b[0]); | ||
78 | ret = -EINVAL; | ||
79 | break; | ||
80 | } | ||
81 | i += 5 + b[0]; | ||
82 | } | ||
83 | /* length in ret */ | ||
84 | if (ret > 0) | ||
85 | ret = 0; | ||
86 | /* restart the CPU */ | 65 | /* restart the CPU */ |
87 | reset = 0; | 66 | reset = 0; |
88 | if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { | 67 | if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { |
89 | err("could not restart the USB controller CPU."); | 68 | err("could not restart the USB controller CPU."); |
90 | ret = -EINVAL; | 69 | ret = -EINVAL; |
91 | } | 70 | } |
71 | } else | ||
72 | ret = -EIO; | ||
92 | 73 | ||
93 | kfree(p); | 74 | return ret; |
94 | } else { | 75 | } |
95 | ret = -ENOMEM; | 76 | EXPORT_SYMBOL(usb_cypress_load_firmware); |
77 | |||
78 | int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props) | ||
79 | { | ||
80 | int ret; | ||
81 | const struct firmware *fw = NULL; | ||
82 | |||
83 | if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { | ||
84 | err("did not find the firmware file. (%s) " | ||
85 | "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", | ||
86 | props->firmware,ret); | ||
87 | return ret; | ||
96 | } | 88 | } |
97 | release_firmware(fw); | ||
98 | 89 | ||
90 | info("downloading firmware from file '%s'",props->firmware); | ||
91 | |||
92 | switch (props->usb_ctrl) { | ||
93 | case CYPRESS_AN2135: | ||
94 | case CYPRESS_AN2235: | ||
95 | case CYPRESS_FX2: | ||
96 | ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl); | ||
97 | break; | ||
98 | case DEVICE_SPECIFIC: | ||
99 | if (props->download_firmware) | ||
100 | ret = props->download_firmware(udev,fw); | ||
101 | else { | ||
102 | err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one."); | ||
103 | ret = -EINVAL; | ||
104 | } | ||
105 | break; | ||
106 | default: | ||
107 | ret = -EINVAL; | ||
108 | break; | ||
109 | } | ||
110 | |||
111 | release_firmware(fw); | ||
99 | return ret; | 112 | return ret; |
100 | } | 113 | } |
114 | |||
115 | int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) | ||
116 | { | ||
117 | u8 *b = (u8 *) &fw->data[*pos]; | ||
118 | int data_offs = 4; | ||
119 | if (*pos >= fw->size) | ||
120 | return 0; | ||
121 | |||
122 | memset(hx,0,sizeof(struct hexline)); | ||
123 | |||
124 | hx->len = b[0]; | ||
125 | |||
126 | if ((*pos + hx->len + 4) >= fw->size) | ||
127 | return -EINVAL; | ||
128 | |||
129 | hx->addr = le16_to_cpu( *((u16 *) &b[1]) ); | ||
130 | hx->type = b[3]; | ||
131 | |||
132 | if (hx->type == 0x04) { | ||
133 | /* b[4] and b[5] are the Extended linear address record data field */ | ||
134 | hx->addr |= (b[4] << 24) | (b[5] << 16); | ||
135 | /* hx->len -= 2; | ||
136 | data_offs += 2; */ | ||
137 | } | ||
138 | memcpy(hx->data,&b[data_offs],hx->len); | ||
139 | hx->chk = b[hx->len + data_offs]; | ||
140 | |||
141 | *pos += hx->len + 5; | ||
142 | |||
143 | return *pos; | ||
144 | } | ||
145 | EXPORT_SYMBOL(dvb_usb_get_hexline); | ||
146 | |||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index da970947dfc7..9b254532af4d 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | |||
@@ -52,9 +52,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | |||
52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; | 52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; |
53 | int ret = 0; | 53 | int ret = 0; |
54 | 54 | ||
55 | /* if there is nothing to initialize */ | 55 | /* if pll_desc is not used */ |
56 | if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 && | 56 | if (d->pll_desc == NULL) |
57 | d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00) | ||
58 | return 0; | 57 | return 0; |
59 | 58 | ||
60 | if (d->tuner_pass_ctrl) | 59 | if (d->tuner_pass_ctrl) |
@@ -80,6 +79,9 @@ int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep | |||
80 | { | 79 | { |
81 | struct dvb_usb_device *d = fe->dvb->priv; | 80 | struct dvb_usb_device *d = fe->dvb->priv; |
82 | 81 | ||
82 | if (d->pll_desc == NULL) | ||
83 | return 0; | ||
84 | |||
83 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); | 85 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); |
84 | 86 | ||
85 | b[0] = d->pll_addr << 1; | 87 | b[0] = d->pll_addr << 1; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 6be99e537e12..d22934383226 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -86,11 +86,15 @@ | |||
86 | #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 | 86 | #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 |
87 | #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 | 87 | #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 |
88 | #define USB_PID_NEBULA_DIGITV 0x0201 | 88 | #define USB_PID_NEBULA_DIGITV 0x0201 |
89 | #define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00 | ||
90 | #define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10 | ||
91 | #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 | 89 | #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 |
92 | #define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 | 90 | #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500 |
93 | #define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 | 91 | #define USB_PID_DVICO_BLUEBIRD_LG064F_WARM 0xd501 |
92 | #define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD 0xdb00 | ||
93 | #define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM 0xdb01 | ||
94 | #define USB_PID_DVICO_BLUEBIRD_TH7579_COLD 0xdb10 | ||
95 | #define USB_PID_DVICO_BLUEBIRD_TH7579_WARM 0xdb11 | ||
96 | #define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD 0xdb50 | ||
97 | #define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM 0xdb51 | ||
94 | #define USB_PID_MEDION_MD95700 0x0932 | 98 | #define USB_PID_MEDION_MD95700 0x0932 |
95 | #define USB_PID_KYE_DVB_T_COLD 0x701e | 99 | #define USB_PID_KYE_DVB_T_COLD 0x701e |
96 | #define USB_PID_KYE_DVB_T_WARM 0x701f | 100 | #define USB_PID_KYE_DVB_T_WARM 0x701f |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index dd8e0b94edba..2e23060cbbca 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c | |||
@@ -138,6 +138,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties | |||
138 | 138 | ||
139 | int ret = -ENOMEM,cold=0; | 139 | int ret = -ENOMEM,cold=0; |
140 | 140 | ||
141 | if (du != NULL) | ||
142 | *du = NULL; | ||
143 | |||
141 | if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { | 144 | if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { |
142 | deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); | 145 | deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); |
143 | return -ENODEV; | 146 | return -ENODEV; |
@@ -145,38 +148,40 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties | |||
145 | 148 | ||
146 | if (cold) { | 149 | if (cold) { |
147 | info("found a '%s' in cold state, will try to load a firmware",desc->name); | 150 | info("found a '%s' in cold state, will try to load a firmware",desc->name); |
148 | ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl); | 151 | ret = dvb_usb_download_firmware(udev,props); |
149 | } else { | 152 | if (!props->no_reconnect) |
150 | info("found a '%s' in warm state.",desc->name); | ||
151 | d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); | ||
152 | if (d == NULL) { | ||
153 | err("no memory for 'struct dvb_usb_device'"); | ||
154 | return ret; | 153 | return ret; |
154 | } | ||
155 | |||
156 | info("found a '%s' in warm state.",desc->name); | ||
157 | d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); | ||
158 | if (d == NULL) { | ||
159 | err("no memory for 'struct dvb_usb_device'"); | ||
160 | return ret; | ||
161 | } | ||
162 | memset(d,0,sizeof(struct dvb_usb_device)); | ||
163 | |||
164 | d->udev = udev; | ||
165 | memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); | ||
166 | d->desc = desc; | ||
167 | d->owner = owner; | ||
168 | |||
169 | if (d->props.size_of_priv > 0) { | ||
170 | d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); | ||
171 | if (d->priv == NULL) { | ||
172 | err("no memory for priv in 'struct dvb_usb_device'"); | ||
173 | kfree(d); | ||
174 | return -ENOMEM; | ||
155 | } | 175 | } |
156 | memset(d,0,sizeof(struct dvb_usb_device)); | 176 | memset(d->priv,0,d->props.size_of_priv); |
157 | 177 | } | |
158 | d->udev = udev; | ||
159 | memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); | ||
160 | d->desc = desc; | ||
161 | d->owner = owner; | ||
162 | |||
163 | if (d->props.size_of_priv > 0) { | ||
164 | d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); | ||
165 | if (d->priv == NULL) { | ||
166 | err("no memory for priv in 'struct dvb_usb_device'"); | ||
167 | kfree(d); | ||
168 | return -ENOMEM; | ||
169 | } | ||
170 | memset(d->priv,0,d->props.size_of_priv); | ||
171 | } | ||
172 | 178 | ||
173 | usb_set_intfdata(intf, d); | 179 | usb_set_intfdata(intf, d); |
174 | 180 | ||
175 | if (du != NULL) | 181 | if (du != NULL) |
176 | *du = d; | 182 | *du = d; |
177 | 183 | ||
178 | ret = dvb_usb_init(d); | 184 | ret = dvb_usb_init(d); |
179 | } | ||
180 | 185 | ||
181 | if (ret == 0) | 186 | if (ret == 0) |
182 | info("%s successfully initialized and connected.",desc->name); | 187 | info("%s successfully initialized and connected.",desc->name); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index b4a1a98006c7..dd568396e594 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -10,8 +10,8 @@ | |||
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
13 | #include <linux/module.h> | ||
14 | #include <linux/usb.h> | 13 | #include <linux/usb.h> |
14 | #include <linux/firmware.h> | ||
15 | 15 | ||
16 | #include "dvb_frontend.h" | 16 | #include "dvb_frontend.h" |
17 | #include "dvb_demux.h" | 17 | #include "dvb_demux.h" |
@@ -94,7 +94,11 @@ struct dvb_usb_device; | |||
94 | * @usb_ctrl: which USB device-side controller is in use. Needed for firmware | 94 | * @usb_ctrl: which USB device-side controller is in use. Needed for firmware |
95 | * download. | 95 | * download. |
96 | * @firmware: name of the firmware file. | 96 | * @firmware: name of the firmware file. |
97 | * | 97 | * @download_firmware: called to download the firmware when the usb_ctrl is |
98 | * DEVICE_SPECIFIC. | ||
99 | * @no_reconnect: device doesn't do a reconnect after downloading the firmware, | ||
100 | so do the warm initialization right after it | ||
101 | |||
98 | * @size_of_priv: how many bytes shall be allocated for the private field | 102 | * @size_of_priv: how many bytes shall be allocated for the private field |
99 | * of struct dvb_usb_device. | 103 | * of struct dvb_usb_device. |
100 | * | 104 | * |
@@ -142,11 +146,14 @@ struct dvb_usb_properties { | |||
142 | int caps; | 146 | int caps; |
143 | int pid_filter_count; | 147 | int pid_filter_count; |
144 | 148 | ||
145 | #define CYPRESS_AN2135 0 | 149 | #define DEVICE_SPECIFIC 0 |
146 | #define CYPRESS_AN2235 1 | 150 | #define CYPRESS_AN2135 1 |
147 | #define CYPRESS_FX2 2 | 151 | #define CYPRESS_AN2235 2 |
152 | #define CYPRESS_FX2 3 | ||
148 | int usb_ctrl; | 153 | int usb_ctrl; |
149 | const char *firmware; | 154 | const char firmware[FIRMWARE_NAME_MAX]; |
155 | int (*download_firmware) (struct usb_device *, const struct firmware *); | ||
156 | int no_reconnect; | ||
150 | 157 | ||
151 | int size_of_priv; | 158 | int size_of_priv; |
152 | 159 | ||
@@ -326,5 +333,15 @@ extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); | |||
326 | extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); | 333 | extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); |
327 | extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); | 334 | extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); |
328 | 335 | ||
336 | /* commonly used firmware download types and function */ | ||
337 | struct hexline { | ||
338 | u8 len; | ||
339 | u32 addr; | ||
340 | u8 type; | ||
341 | u8 data[255]; | ||
342 | u8 chk; | ||
343 | }; | ||
344 | extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *); | ||
345 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); | ||
329 | 346 | ||
330 | #endif | 347 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index fac48fc7a4ac..412039d8dbae 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c | |||
@@ -129,10 +129,6 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) | |||
129 | dibusb_read_eeprom_byte(d,i, &b); | 129 | dibusb_read_eeprom_byte(d,i, &b); |
130 | 130 | ||
131 | mac[5 - (i - 136)] = b; | 131 | mac[5 - (i - 136)] = b; |
132 | |||
133 | /* deb_ee("%02x ",b); | ||
134 | if ((i+1) % 16 == 0) | ||
135 | deb_ee("\n");*/ | ||
136 | } | 132 | } |
137 | 133 | ||
138 | return 0; | 134 | return 0; |
@@ -153,7 +149,7 @@ static struct usb_device_id nova_t_table [] = { | |||
153 | /* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, | 149 | /* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, |
154 | { } /* Terminating entry */ | 150 | { } /* Terminating entry */ |
155 | }; | 151 | }; |
156 | MODULE_DEVICE_TABLE (usb, nova_t_table); | 152 | MODULE_DEVICE_TABLE(usb, nova_t_table); |
157 | 153 | ||
158 | static struct dvb_usb_properties nova_t_properties = { | 154 | static struct dvb_usb_properties nova_t_properties = { |
159 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, | 155 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -198,6 +194,7 @@ static struct dvb_usb_properties nova_t_properties = { | |||
198 | { &nova_t_table[0], NULL }, | 194 | { &nova_t_table[0], NULL }, |
199 | { &nova_t_table[1], NULL }, | 195 | { &nova_t_table[1], NULL }, |
200 | }, | 196 | }, |
197 | { NULL }, | ||
201 | } | 198 | } |
202 | }; | 199 | }; |
203 | 200 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 104b5d016c7b..0885d9fb2bf2 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c | |||
@@ -190,7 +190,7 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe, | |||
190 | } | 190 | } |
191 | 191 | ||
192 | static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, | 192 | static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, |
193 | struct dvb_diseqc_master_cmd *m) | 193 | struct dvb_diseqc_master_cmd *m) |
194 | { | 194 | { |
195 | struct vp702x_fe_state *st = fe->demodulator_priv; | 195 | struct vp702x_fe_state *st = fe->demodulator_priv; |
196 | u8 cmd[8],ibuf[10]; | 196 | u8 cmd[8],ibuf[10]; |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h index 4a3e8c7eca2b..a808d48e7bf2 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.h +++ b/drivers/media/dvb/dvb-usb/vp702x.h | |||
@@ -13,47 +13,47 @@ extern int dvb_usb_vp702x_debug; | |||
13 | /* commands are read and written with USB control messages */ | 13 | /* commands are read and written with USB control messages */ |
14 | 14 | ||
15 | /* consecutive read/write operation */ | 15 | /* consecutive read/write operation */ |
16 | #define REQUEST_OUT 0xB2 | 16 | #define REQUEST_OUT 0xB2 |
17 | #define REQUEST_IN 0xB3 | 17 | #define REQUEST_IN 0xB3 |
18 | 18 | ||
19 | /* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 | 19 | /* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 |
20 | * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer | 20 | * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer |
21 | * the returning buffer looks as follows | 21 | * the returning buffer looks as follows |
22 | * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ | 22 | * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ |
23 | 23 | ||
24 | #define GET_TUNER_STATUS 0x05 | 24 | #define GET_TUNER_STATUS 0x05 |
25 | /* additional in buffer: | 25 | /* additional in buffer: |
26 | * 0 1 2 3 4 5 6 7 8 | 26 | * 0 1 2 3 4 5 6 7 8 |
27 | * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ | 27 | * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ |
28 | 28 | ||
29 | #define GET_SYSTEM_STRING 0x06 | 29 | #define GET_SYSTEM_STRING 0x06 |
30 | /* additional in buffer: | 30 | /* additional in buffer: |
31 | * 0 1 2 3 4 5 6 7 8 | 31 | * 0 1 2 3 4 5 6 7 8 |
32 | * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ | 32 | * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ |
33 | 33 | ||
34 | #define SET_DISEQC_CMD 0x08 | 34 | #define SET_DISEQC_CMD 0x08 |
35 | /* additional out buffer: | 35 | /* additional out buffer: |
36 | * 0 1 2 3 4 | 36 | * 0 1 2 3 4 |
37 | * len X1 X2 X3 X4 | 37 | * len X1 X2 X3 X4 |
38 | * additional in buffer: | 38 | * additional in buffer: |
39 | * 0 1 2 | 39 | * 0 1 2 |
40 | * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ | 40 | * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */ |
41 | 41 | ||
42 | #define SET_LNB_POWER 0x09 | 42 | #define SET_LNB_POWER 0x09 |
43 | /* additional out buffer: | 43 | /* additional out buffer: |
44 | * 0 1 2 | 44 | * 0 1 2 |
45 | * 0x00 0xff 1 = on, 0 = off | 45 | * 0x00 0xff 1 = on, 0 = off |
46 | * additional in buffer: | 46 | * additional in buffer: |
47 | * 0 1 2 | 47 | * 0 1 2 |
48 | * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ | 48 | * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */ |
49 | 49 | ||
50 | #define GET_MAC_ADDRESS 0x0A | 50 | #define GET_MAC_ADDRESS 0x0A |
51 | /* #define GET_MAC_ADDRESS 0x0B */ | 51 | /* #define GET_MAC_ADDRESS 0x0B */ |
52 | /* additional in buffer: | 52 | /* additional in buffer: |
53 | * 0 1 2 3 4 5 6 7 8 | 53 | * 0 1 2 3 4 5 6 7 8 |
54 | * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ | 54 | * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ |
55 | 55 | ||
56 | #define SET_PID_FILTER 0x11 | 56 | #define SET_PID_FILTER 0x11 |
57 | /* additional in buffer: | 57 | /* additional in buffer: |
58 | * 0 1 ... 14 15 16 | 58 | * 0 1 ... 14 15 16 |
59 | * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ | 59 | * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ |
@@ -64,39 +64,38 @@ extern int dvb_usb_vp702x_debug; | |||
64 | * freq0 freq1 divstep srate0 srate1 srate2 flag chksum | 64 | * freq0 freq1 divstep srate0 srate1 srate2 flag chksum |
65 | */ | 65 | */ |
66 | 66 | ||
67 | |||
68 | /* one direction requests */ | 67 | /* one direction requests */ |
69 | #define READ_REMOTE_REQ 0xB4 | 68 | #define READ_REMOTE_REQ 0xB4 |
70 | /* IN i: 0; v: 0; b[0] == request, b[1] == key */ | 69 | /* IN i: 0; v: 0; b[0] == request, b[1] == key */ |
71 | 70 | ||
72 | #define READ_PID_NUMBER_REQ 0xB5 | 71 | #define READ_PID_NUMBER_REQ 0xB5 |
73 | /* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ | 72 | /* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ |
74 | 73 | ||
75 | #define WRITE_EEPROM_REQ 0xB6 | 74 | #define WRITE_EEPROM_REQ 0xB6 |
76 | /* OUT i: offset; v: value to write; no extra buffer */ | 75 | /* OUT i: offset; v: value to write; no extra buffer */ |
77 | 76 | ||
78 | #define READ_EEPROM_REQ 0xB7 | 77 | #define READ_EEPROM_REQ 0xB7 |
79 | /* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ | 78 | /* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ |
80 | 79 | ||
81 | #define READ_STATUS 0xB8 | 80 | #define READ_STATUS 0xB8 |
82 | /* IN i: 0; v: 0; bufferlen 10 */ | 81 | /* IN i: 0; v: 0; bufferlen 10 */ |
83 | 82 | ||
84 | #define READ_TUNER_REG_REQ 0xB9 | 83 | #define READ_TUNER_REG_REQ 0xB9 |
85 | /* IN i: 0; v: register; b[0] = value */ | 84 | /* IN i: 0; v: register; b[0] = value */ |
86 | 85 | ||
87 | #define READ_FX2_REG_REQ 0xBA | 86 | #define READ_FX2_REG_REQ 0xBA |
88 | /* IN i: offset; v: 0; b[0] = value */ | 87 | /* IN i: offset; v: 0; b[0] = value */ |
89 | 88 | ||
90 | #define WRITE_FX2_REG_REQ 0xBB | 89 | #define WRITE_FX2_REG_REQ 0xBB |
91 | /* OUT i: offset; v: value to write; 1 byte extra buffer */ | 90 | /* OUT i: offset; v: value to write; 1 byte extra buffer */ |
92 | 91 | ||
93 | #define SET_TUNER_POWER_REQ 0xBC | 92 | #define SET_TUNER_POWER_REQ 0xBC |
94 | /* IN i: 0 = power off, 1 = power on */ | 93 | /* IN i: 0 = power off, 1 = power on */ |
95 | 94 | ||
96 | #define WRITE_TUNER_REG_REQ 0xBD | 95 | #define WRITE_TUNER_REG_REQ 0xBD |
97 | /* IN i: register, v: value to write, no extra buffer */ | 96 | /* IN i: register, v: value to write, no extra buffer */ |
98 | 97 | ||
99 | #define RESET_TUNER 0xBE | 98 | #define RESET_TUNER 0xBE |
100 | /* IN i: 0, v: 0, no extra buffer */ | 99 | /* IN i: 0, v: 0, no extra buffer */ |
101 | 100 | ||
102 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); | 101 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 3835235b68df..028204956bb0 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { | |||
247 | .cold_ids = { &vp7045_usb_table[2], NULL }, | 247 | .cold_ids = { &vp7045_usb_table[2], NULL }, |
248 | .warm_ids = { &vp7045_usb_table[3], NULL }, | 248 | .warm_ids = { &vp7045_usb_table[3], NULL }, |
249 | }, | 249 | }, |
250 | { NULL }, | 250 | { 0 }, |
251 | } | 251 | } |
252 | }; | 252 | }; |
253 | 253 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 8e269e1c1f9d..db3a8b40031e 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -16,6 +16,12 @@ config DVB_CX24110 | |||
16 | help | 16 | help |
17 | A DVB-S tuner module. Say Y when you want to support this frontend. | 17 | A DVB-S tuner module. Say Y when you want to support this frontend. |
18 | 18 | ||
19 | config DVB_CX24123 | ||
20 | tristate "Conexant CX24123 based" | ||
21 | depends on DVB_CORE | ||
22 | help | ||
23 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
24 | |||
19 | config DVB_TDA8083 | 25 | config DVB_TDA8083 |
20 | tristate "Philips TDA8083 based" | 26 | tristate "Philips TDA8083 based" |
21 | depends on DVB_CORE | 27 | depends on DVB_CORE |
@@ -50,18 +56,19 @@ comment "DVB-T (terrestrial) frontends" | |||
50 | depends on DVB_CORE | 56 | depends on DVB_CORE |
51 | 57 | ||
52 | config DVB_SP8870 | 58 | config DVB_SP8870 |
53 | tristate "Spase sp8870 based" | 59 | tristate "Spase sp8870 based" |
54 | depends on DVB_CORE | 60 | depends on DVB_CORE |
55 | select FW_LOADER | 61 | select FW_LOADER |
56 | help | 62 | help |
57 | A DVB-T tuner module. Say Y when you want to support this frontend. | 63 | A DVB-T tuner module. Say Y when you want to support this frontend. |
58 | 64 | ||
59 | This driver needs external firmware. Please use the command | 65 | This driver needs external firmware. Please use the command |
60 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to | 66 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to |
61 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 67 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
68 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
62 | 69 | ||
63 | config DVB_SP887X | 70 | config DVB_SP887X |
64 | tristate "Spase sp887x based" | 71 | tristate "Spase sp887x based" |
65 | depends on DVB_CORE | 72 | depends on DVB_CORE |
66 | select FW_LOADER | 73 | select FW_LOADER |
67 | help | 74 | help |
@@ -69,7 +76,8 @@ config DVB_SP887X | |||
69 | 76 | ||
70 | This driver needs external firmware. Please use the command | 77 | This driver needs external firmware. Please use the command |
71 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to | 78 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to |
72 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 79 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
80 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
73 | 81 | ||
74 | config DVB_CX22700 | 82 | config DVB_CX22700 |
75 | tristate "Conexant CX22700 based" | 83 | tristate "Conexant CX22700 based" |
@@ -78,10 +86,10 @@ config DVB_CX22700 | |||
78 | A DVB-T tuner module. Say Y when you want to support this frontend. | 86 | A DVB-T tuner module. Say Y when you want to support this frontend. |
79 | 87 | ||
80 | config DVB_CX22702 | 88 | config DVB_CX22702 |
81 | tristate "Conexant cx22702 demodulator (OFDM)" | 89 | tristate "Conexant cx22702 demodulator (OFDM)" |
82 | depends on DVB_CORE | 90 | depends on DVB_CORE |
83 | help | 91 | help |
84 | A DVB-T tuner module. Say Y when you want to support this frontend. | 92 | A DVB-T tuner module. Say Y when you want to support this frontend. |
85 | 93 | ||
86 | config DVB_L64781 | 94 | config DVB_L64781 |
87 | tristate "LSI L64781" | 95 | tristate "LSI L64781" |
@@ -98,8 +106,9 @@ config DVB_TDA1004X | |||
98 | 106 | ||
99 | This driver needs external firmware. Please use the commands | 107 | This driver needs external firmware. Please use the commands |
100 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", | 108 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", |
101 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to | 109 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to |
102 | download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 110 | download/extract them, and then copy them to /usr/lib/hotplug/firmware |
111 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
103 | 112 | ||
104 | config DVB_NXT6000 | 113 | config DVB_NXT6000 |
105 | tristate "NxtWave Communications NXT6000 based" | 114 | tristate "NxtWave Communications NXT6000 based" |
@@ -140,13 +149,13 @@ config DVB_VES1820 | |||
140 | tristate "VLSI VES1820 based" | 149 | tristate "VLSI VES1820 based" |
141 | depends on DVB_CORE | 150 | depends on DVB_CORE |
142 | help | 151 | help |
143 | A DVB-C tuner module. Say Y when you want to support this frontend. | 152 | A DVB-C tuner module. Say Y when you want to support this frontend. |
144 | 153 | ||
145 | config DVB_TDA10021 | 154 | config DVB_TDA10021 |
146 | tristate "Philips TDA10021 based" | 155 | tristate "Philips TDA10021 based" |
147 | depends on DVB_CORE | 156 | depends on DVB_CORE |
148 | help | 157 | help |
149 | A DVB-C tuner module. Say Y when you want to support this frontend. | 158 | A DVB-C tuner module. Say Y when you want to support this frontend. |
150 | 159 | ||
151 | config DVB_STV0297 | 160 | config DVB_STV0297 |
152 | tristate "ST STV0297 based" | 161 | tristate "ST STV0297 based" |
@@ -164,6 +173,11 @@ config DVB_NXT2002 | |||
164 | help | 173 | help |
165 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 174 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
166 | 175 | ||
176 | This driver needs external firmware. Please use the command | ||
177 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
178 | download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
179 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
180 | |||
167 | config DVB_NXT200X | 181 | config DVB_NXT200X |
168 | tristate "Nextwave NXT2002/NXT2004 based" | 182 | tristate "Nextwave NXT2002/NXT2004 based" |
169 | depends on DVB_CORE | 183 | depends on DVB_CORE |
@@ -172,6 +186,12 @@ config DVB_NXT200X | |||
172 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 186 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
173 | to support this frontend. | 187 | to support this frontend. |
174 | 188 | ||
189 | This driver needs external firmware. Please use the commands | ||
190 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and | ||
191 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to | ||
192 | download/extract them, and then copy them to /usr/lib/hotplug/firmware | ||
193 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
194 | |||
175 | config DVB_OR51211 | 195 | config DVB_OR51211 |
176 | tristate "or51211 based (pcHDTV HD2000 card)" | 196 | tristate "or51211 based (pcHDTV HD2000 card)" |
177 | depends on DVB_CORE | 197 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a98760fe08a1..615ec830e1c9 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -32,3 +32,4 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o | |||
32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | 32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o |
33 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 33 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
34 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 34 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
35 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | ||
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 8ceb9a33c7af..3b132bafd4de 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c | |||
@@ -255,7 +255,7 @@ static int bcm3510_bert_reset(struct bcm3510_state *st) | |||
255 | bcm3510_register_value b; | 255 | bcm3510_register_value b; |
256 | int ret; | 256 | int ret; |
257 | 257 | ||
258 | if ((ret < bcm3510_readB(st,0xfa,&b)) < 0) | 258 | if ((ret = bcm3510_readB(st,0xfa,&b)) < 0) |
259 | return ret; | 259 | return ret; |
260 | 260 | ||
261 | b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); | 261 | b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); |
@@ -623,13 +623,13 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe) | |||
623 | err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); | 623 | err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); |
624 | return ret; | 624 | return ret; |
625 | } | 625 | } |
626 | deb_info("got firmware: %d\n",fw->size); | 626 | deb_info("got firmware: %zd\n",fw->size); |
627 | 627 | ||
628 | b = fw->data; | 628 | b = fw->data; |
629 | for (i = 0; i < fw->size;) { | 629 | for (i = 0; i < fw->size;) { |
630 | addr = le16_to_cpu( *( (u16 *)&b[i] ) ); | 630 | addr = le16_to_cpu( *( (u16 *)&b[i] ) ); |
631 | len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); | 631 | len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); |
632 | deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size); | 632 | deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); |
633 | if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { | 633 | if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { |
634 | err("firmware download failed: %d\n",ret); | 634 | err("firmware download failed: %d\n",ret); |
635 | return ret; | 635 | return ret; |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 5de0e6d350b1..0fc899f81c5e 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -195,6 +195,16 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet | |||
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
199 | { | ||
200 | struct cx22702_state* state = fe->demodulator_priv; | ||
201 | dprintk ("%s(%d)\n", __FUNCTION__, enable); | ||
202 | if (enable) | ||
203 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); | ||
204 | else | ||
205 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); | ||
206 | } | ||
207 | |||
198 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 208 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
199 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 209 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
200 | { | 210 | { |
@@ -202,7 +212,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
202 | struct cx22702_state* state = fe->demodulator_priv; | 212 | struct cx22702_state* state = fe->demodulator_priv; |
203 | 213 | ||
204 | /* set PLL */ | 214 | /* set PLL */ |
205 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); | 215 | cx22702_i2c_gate_ctrl(fe, 1); |
206 | if (state->config->pll_set) { | 216 | if (state->config->pll_set) { |
207 | state->config->pll_set(fe, p); | 217 | state->config->pll_set(fe, p); |
208 | } else if (state->config->pll_desc) { | 218 | } else if (state->config->pll_desc) { |
@@ -216,7 +226,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
216 | } else { | 226 | } else { |
217 | BUG(); | 227 | BUG(); |
218 | } | 228 | } |
219 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 229 | cx22702_i2c_gate_ctrl(fe, 0); |
220 | 230 | ||
221 | /* set inversion */ | 231 | /* set inversion */ |
222 | cx22702_set_inversion (state, p->inversion); | 232 | cx22702_set_inversion (state, p->inversion); |
@@ -349,11 +359,10 @@ static int cx22702_init (struct dvb_frontend* fe) | |||
349 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 359 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); |
350 | 360 | ||
351 | /* init PLL */ | 361 | /* init PLL */ |
352 | if (state->config->pll_init) { | 362 | if (state->config->pll_init) |
353 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe); | ||
354 | state->config->pll_init(fe); | 363 | state->config->pll_init(fe); |
355 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 364 | |
356 | } | 365 | cx22702_i2c_gate_ctrl(fe, 0); |
357 | 366 | ||
358 | return 0; | 367 | return 0; |
359 | } | 368 | } |
@@ -531,6 +540,7 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
531 | .read_signal_strength = cx22702_read_signal_strength, | 540 | .read_signal_strength = cx22702_read_signal_strength, |
532 | .read_snr = cx22702_read_snr, | 541 | .read_snr = cx22702_read_snr, |
533 | .read_ucblocks = cx22702_read_ucblocks, | 542 | .read_ucblocks = cx22702_read_ucblocks, |
543 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
534 | }; | 544 | }; |
535 | 545 | ||
536 | module_param(debug, int, 0644); | 546 | module_param(debug, int, 0644); |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 0c4db80ec332..d15d32c51dc5 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/jiffies.h> | ||
31 | 30 | ||
32 | #include "dvb_frontend.h" | 31 | #include "dvb_frontend.h" |
33 | #include "cx24110.h" | 32 | #include "cx24110.h" |
@@ -56,7 +55,7 @@ static int debug; | |||
56 | 55 | ||
57 | static struct {u8 reg; u8 data;} cx24110_regdata[]= | 56 | static struct {u8 reg; u8 data;} cx24110_regdata[]= |
58 | /* Comments beginning with @ denote this value should | 57 | /* Comments beginning with @ denote this value should |
59 | be the default */ | 58 | be the default */ |
60 | {{0x09,0x01}, /* SoftResetAll */ | 59 | {{0x09,0x01}, /* SoftResetAll */ |
61 | {0x09,0x00}, /* release reset */ | 60 | {0x09,0x00}, /* release reset */ |
62 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ | 61 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ |
@@ -67,26 +66,26 @@ static struct {u8 reg; u8 data;} cx24110_regdata[]= | |||
67 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ | 66 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ |
68 | {0x0a,0x00}, /* @ partial chip disables, do not set */ | 67 | {0x0a,0x00}, /* @ partial chip disables, do not set */ |
69 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low | 68 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low |
70 | active for first byte */ | 69 | active for first byte */ |
71 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ | 70 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ |
72 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ | 71 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ |
73 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 | 72 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 |
74 | to avoid starting the BER counter. Reset the | 73 | to avoid starting the BER counter. Reset the |
75 | CRC test bit. Finite counting selected */ | 74 | CRC test bit. Finite counting selected */ |
76 | {0x15,0xff}, /* @ size of the limited time window for RS BER | 75 | {0x15,0xff}, /* @ size of the limited time window for RS BER |
77 | estimation. It is <value>*256 RS blocks, this | 76 | estimation. It is <value>*256 RS blocks, this |
78 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ | 77 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ |
79 | {0x16,0x00}, /* @ enable all RS output ports */ | 78 | {0x16,0x00}, /* @ enable all RS output ports */ |
80 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ | 79 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ |
81 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned | 80 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned |
82 | for automatically */ | 81 | for automatically */ |
83 | /* leave the current code rate and normalization | 82 | /* leave the current code rate and normalization |
84 | registers as they are after reset... */ | 83 | registers as they are after reset... */ |
85 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting | 84 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting |
86 | only once */ | 85 | only once */ |
87 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER | 86 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER |
88 | estimation. It is <value>*65536 channel bits, i.e. | 87 | estimation. It is <value>*65536 channel bits, i.e. |
89 | approx. 38ms at 27.5MS/s, rate 3/4 */ | 88 | approx. 38ms at 27.5MS/s, rate 3/4 */ |
90 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ | 89 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ |
91 | /* leave front-end AGC parameters at default values */ | 90 | /* leave front-end AGC parameters at default values */ |
92 | /* leave decimation AGC parameters at default values */ | 91 | /* leave decimation AGC parameters at default values */ |
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c new file mode 100644 index 000000000000..d661c6f9cbe5 --- /dev/null +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -0,0 +1,889 @@ | |||
1 | /* | ||
2 | Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> | ||
5 | |||
6 | Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/slab.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #include "dvb_frontend.h" | ||
30 | #include "cx24123.h" | ||
31 | |||
32 | static int debug; | ||
33 | #define dprintk(args...) \ | ||
34 | do { \ | ||
35 | if (debug) printk (KERN_DEBUG "cx24123: " args); \ | ||
36 | } while (0) | ||
37 | |||
38 | struct cx24123_state | ||
39 | { | ||
40 | struct i2c_adapter* i2c; | ||
41 | struct dvb_frontend_ops ops; | ||
42 | const struct cx24123_config* config; | ||
43 | |||
44 | struct dvb_frontend frontend; | ||
45 | |||
46 | u32 lastber; | ||
47 | u16 snr; | ||
48 | u8 lnbreg; | ||
49 | |||
50 | /* Some PLL specifics for tuning */ | ||
51 | u32 VCAarg; | ||
52 | u32 VGAarg; | ||
53 | u32 bandselectarg; | ||
54 | u32 pllarg; | ||
55 | |||
56 | /* The Demod/Tuner can't easily provide these, we cache them */ | ||
57 | u32 currentfreq; | ||
58 | u32 currentsymbolrate; | ||
59 | }; | ||
60 | |||
61 | /* Various tuner defaults need to be established for a given symbol rate Sps */ | ||
62 | static struct | ||
63 | { | ||
64 | u32 symbolrate_low; | ||
65 | u32 symbolrate_high; | ||
66 | u32 VCAslope; | ||
67 | u32 VCAoffset; | ||
68 | u32 VGA1offset; | ||
69 | u32 VGA2offset; | ||
70 | u32 VCAprogdata; | ||
71 | u32 VGAprogdata; | ||
72 | } cx24123_AGC_vals[] = | ||
73 | { | ||
74 | { | ||
75 | .symbolrate_low = 1000000, | ||
76 | .symbolrate_high = 4999999, | ||
77 | .VCAslope = 0x07, | ||
78 | .VCAoffset = 0x0f, | ||
79 | .VGA1offset = 0x1f8, | ||
80 | .VGA2offset = 0x1f8, | ||
81 | .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8, | ||
82 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07, | ||
83 | }, | ||
84 | { | ||
85 | .symbolrate_low = 5000000, | ||
86 | .symbolrate_high = 14999999, | ||
87 | .VCAslope = 0x1f, | ||
88 | .VCAoffset = 0x1f, | ||
89 | .VGA1offset = 0x1e0, | ||
90 | .VGA2offset = 0x180, | ||
91 | .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0, | ||
92 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f, | ||
93 | }, | ||
94 | { | ||
95 | .symbolrate_low = 15000000, | ||
96 | .symbolrate_high = 45000000, | ||
97 | .VCAslope = 0x3f, | ||
98 | .VCAoffset = 0x3f, | ||
99 | .VGA1offset = 0x180, | ||
100 | .VGA2offset = 0x100, | ||
101 | .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180, | ||
102 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * Various tuner defaults need to be established for a given frequency kHz. | ||
108 | * fixme: The bounds on the bands do not match the doc in real life. | ||
109 | * fixme: Some of them have been moved, other might need adjustment. | ||
110 | */ | ||
111 | static struct | ||
112 | { | ||
113 | u32 freq_low; | ||
114 | u32 freq_high; | ||
115 | u32 bandselect; | ||
116 | u32 VCOdivider; | ||
117 | u32 VCOnumber; | ||
118 | u32 progdata; | ||
119 | } cx24123_bandselect_vals[] = | ||
120 | { | ||
121 | { | ||
122 | .freq_low = 950000, | ||
123 | .freq_high = 1018999, | ||
124 | .bandselect = 0x40, | ||
125 | .VCOdivider = 4, | ||
126 | .VCOnumber = 7, | ||
127 | .progdata = (0 << 18) | (0 << 9) | 0x40, | ||
128 | }, | ||
129 | { | ||
130 | .freq_low = 1019000, | ||
131 | .freq_high = 1074999, | ||
132 | .bandselect = 0x80, | ||
133 | .VCOdivider = 4, | ||
134 | .VCOnumber = 8, | ||
135 | .progdata = (0 << 18) | (0 << 9) | 0x80, | ||
136 | }, | ||
137 | { | ||
138 | .freq_low = 1075000, | ||
139 | .freq_high = 1227999, | ||
140 | .bandselect = 0x01, | ||
141 | .VCOdivider = 2, | ||
142 | .VCOnumber = 1, | ||
143 | .progdata = (0 << 18) | (1 << 9) | 0x01, | ||
144 | }, | ||
145 | { | ||
146 | .freq_low = 1228000, | ||
147 | .freq_high = 1349999, | ||
148 | .bandselect = 0x02, | ||
149 | .VCOdivider = 2, | ||
150 | .VCOnumber = 2, | ||
151 | .progdata = (0 << 18) | (1 << 9) | 0x02, | ||
152 | }, | ||
153 | { | ||
154 | .freq_low = 1350000, | ||
155 | .freq_high = 1481999, | ||
156 | .bandselect = 0x04, | ||
157 | .VCOdivider = 2, | ||
158 | .VCOnumber = 3, | ||
159 | .progdata = (0 << 18) | (1 << 9) | 0x04, | ||
160 | }, | ||
161 | { | ||
162 | .freq_low = 1482000, | ||
163 | .freq_high = 1595999, | ||
164 | .bandselect = 0x08, | ||
165 | .VCOdivider = 2, | ||
166 | .VCOnumber = 4, | ||
167 | .progdata = (0 << 18) | (1 << 9) | 0x08, | ||
168 | }, | ||
169 | { | ||
170 | .freq_low = 1596000, | ||
171 | .freq_high = 1717999, | ||
172 | .bandselect = 0x10, | ||
173 | .VCOdivider = 2, | ||
174 | .VCOnumber = 5, | ||
175 | .progdata = (0 << 18) | (1 << 9) | 0x10, | ||
176 | }, | ||
177 | { | ||
178 | .freq_low = 1718000, | ||
179 | .freq_high = 1855999, | ||
180 | .bandselect = 0x20, | ||
181 | .VCOdivider = 2, | ||
182 | .VCOnumber = 6, | ||
183 | .progdata = (0 << 18) | (1 << 9) | 0x20, | ||
184 | }, | ||
185 | { | ||
186 | .freq_low = 1856000, | ||
187 | .freq_high = 2035999, | ||
188 | .bandselect = 0x40, | ||
189 | .VCOdivider = 2, | ||
190 | .VCOnumber = 7, | ||
191 | .progdata = (0 << 18) | (1 << 9) | 0x40, | ||
192 | }, | ||
193 | { | ||
194 | .freq_low = 2036000, | ||
195 | .freq_high = 2149999, | ||
196 | .bandselect = 0x80, | ||
197 | .VCOdivider = 2, | ||
198 | .VCOnumber = 8, | ||
199 | .progdata = (0 << 18) | (1 << 9) | 0x80, | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static struct { | ||
204 | u8 reg; | ||
205 | u8 data; | ||
206 | } cx24123_regdata[] = | ||
207 | { | ||
208 | {0x00, 0x03}, /* Reset system */ | ||
209 | {0x00, 0x00}, /* Clear reset */ | ||
210 | {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */ | ||
211 | {0x03, 0x07}, | ||
212 | {0x04, 0x10}, | ||
213 | {0x05, 0x04}, | ||
214 | {0x06, 0x31}, | ||
215 | {0x0d, 0x02}, | ||
216 | {0x0e, 0x03}, | ||
217 | {0x0f, 0xfe}, | ||
218 | {0x10, 0x01}, | ||
219 | {0x14, 0x01}, | ||
220 | {0x15, 0x98}, | ||
221 | {0x16, 0x00}, | ||
222 | {0x17, 0x01}, | ||
223 | {0x1b, 0x05}, | ||
224 | {0x1c, 0x80}, | ||
225 | {0x1d, 0x00}, | ||
226 | {0x1e, 0x00}, | ||
227 | {0x20, 0x41}, | ||
228 | {0x21, 0x15}, | ||
229 | {0x27, 0x14}, | ||
230 | {0x28, 0x46}, | ||
231 | {0x29, 0x00}, | ||
232 | {0x2a, 0xb0}, | ||
233 | {0x2b, 0x73}, | ||
234 | {0x2c, 0x00}, | ||
235 | {0x2d, 0x00}, | ||
236 | {0x2e, 0x00}, | ||
237 | {0x2f, 0x00}, | ||
238 | {0x30, 0x00}, | ||
239 | {0x31, 0x00}, | ||
240 | {0x32, 0x8c}, | ||
241 | {0x33, 0x00}, | ||
242 | {0x34, 0x00}, | ||
243 | {0x35, 0x03}, | ||
244 | {0x36, 0x02}, | ||
245 | {0x37, 0x3a}, | ||
246 | {0x3a, 0x00}, /* Enable AGC accumulator */ | ||
247 | {0x44, 0x00}, | ||
248 | {0x45, 0x00}, | ||
249 | {0x46, 0x05}, | ||
250 | {0x56, 0x41}, | ||
251 | {0x57, 0xff}, | ||
252 | {0x67, 0x83}, | ||
253 | }; | ||
254 | |||
255 | static int cx24123_writereg(struct cx24123_state* state, int reg, int data) | ||
256 | { | ||
257 | u8 buf[] = { reg, data }; | ||
258 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
259 | int err; | ||
260 | |||
261 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
262 | printk("%s: writereg error(err == %i, reg == 0x%02x," | ||
263 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
264 | return -EREMOTEIO; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) | ||
271 | { | ||
272 | u8 buf[] = { reg, data }; | ||
273 | /* fixme: put the intersil addr int the config */ | ||
274 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; | ||
275 | int err; | ||
276 | |||
277 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
278 | printk("%s: writelnbreg error (err == %i, reg == 0x%02x," | ||
279 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
280 | return -EREMOTEIO; | ||
281 | } | ||
282 | |||
283 | /* cache the write, no way to read back */ | ||
284 | state->lnbreg = data; | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) | ||
290 | { | ||
291 | int ret; | ||
292 | u8 b0[] = { reg }; | ||
293 | u8 b1[] = { 0 }; | ||
294 | struct i2c_msg msg[] = { | ||
295 | { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | ||
296 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } | ||
297 | }; | ||
298 | |||
299 | ret = i2c_transfer(state->i2c, msg, 2); | ||
300 | |||
301 | if (ret != 2) { | ||
302 | printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | return b1[0]; | ||
307 | } | ||
308 | |||
309 | static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) | ||
310 | { | ||
311 | return state->lnbreg; | ||
312 | } | ||
313 | |||
314 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | ||
315 | { | ||
316 | switch (inversion) { | ||
317 | case INVERSION_OFF: | ||
318 | cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f); | ||
319 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); | ||
320 | break; | ||
321 | case INVERSION_ON: | ||
322 | cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80); | ||
323 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); | ||
324 | break; | ||
325 | case INVERSION_AUTO: | ||
326 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f); | ||
327 | break; | ||
328 | default: | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion) | ||
336 | { | ||
337 | u8 val; | ||
338 | |||
339 | val = cx24123_readreg(state, 0x1b) >> 7; | ||
340 | |||
341 | if (val == 0) | ||
342 | *inversion = INVERSION_OFF; | ||
343 | else | ||
344 | *inversion = INVERSION_ON; | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) | ||
350 | { | ||
351 | if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) | ||
352 | fec = FEC_AUTO; | ||
353 | |||
354 | /* Hardware has 5/11 and 3/5 but are never unused */ | ||
355 | switch (fec) { | ||
356 | case FEC_NONE: | ||
357 | return cx24123_writereg(state, 0x0f, 0x01); | ||
358 | case FEC_1_2: | ||
359 | return cx24123_writereg(state, 0x0f, 0x02); | ||
360 | case FEC_2_3: | ||
361 | return cx24123_writereg(state, 0x0f, 0x04); | ||
362 | case FEC_3_4: | ||
363 | return cx24123_writereg(state, 0x0f, 0x08); | ||
364 | case FEC_5_6: | ||
365 | return cx24123_writereg(state, 0x0f, 0x20); | ||
366 | case FEC_7_8: | ||
367 | return cx24123_writereg(state, 0x0f, 0x80); | ||
368 | case FEC_AUTO: | ||
369 | return cx24123_writereg(state, 0x0f, 0xae); | ||
370 | default: | ||
371 | return -EOPNOTSUPP; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) | ||
376 | { | ||
377 | int ret; | ||
378 | u8 val; | ||
379 | |||
380 | ret = cx24123_readreg (state, 0x1b); | ||
381 | if (ret < 0) | ||
382 | return ret; | ||
383 | val = ret & 0x07; | ||
384 | switch (val) { | ||
385 | case 1: | ||
386 | *fec = FEC_1_2; | ||
387 | break; | ||
388 | case 3: | ||
389 | *fec = FEC_2_3; | ||
390 | break; | ||
391 | case 4: | ||
392 | *fec = FEC_3_4; | ||
393 | break; | ||
394 | case 5: | ||
395 | *fec = FEC_4_5; | ||
396 | break; | ||
397 | case 6: | ||
398 | *fec = FEC_5_6; | ||
399 | break; | ||
400 | case 7: | ||
401 | *fec = FEC_7_8; | ||
402 | break; | ||
403 | case 2: /* *fec = FEC_3_5; break; */ | ||
404 | case 0: /* *fec = FEC_5_11; break; */ | ||
405 | *fec = FEC_AUTO; | ||
406 | break; | ||
407 | default: | ||
408 | *fec = FEC_NONE; // can't happen | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* fixme: Symbol rates < 3MSps may not work because of precision loss */ | ||
415 | static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | ||
416 | { | ||
417 | u32 val; | ||
418 | |||
419 | val = (srate / 1185) * 100; | ||
420 | |||
421 | /* Compensate for scaling up, by removing 17 symbols per 1Msps */ | ||
422 | val = val - (17 * (srate / 1000000)); | ||
423 | |||
424 | cx24123_writereg(state, 0x08, (val >> 16) & 0xff ); | ||
425 | cx24123_writereg(state, 0x09, (val >> 8) & 0xff ); | ||
426 | cx24123_writereg(state, 0x0a, (val ) & 0xff ); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Based on the required frequency and symbolrate, the tuner AGC has to be configured | ||
433 | * and the correct band selected. Calculate those values | ||
434 | */ | ||
435 | static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
436 | { | ||
437 | struct cx24123_state *state = fe->demodulator_priv; | ||
438 | u32 ndiv = 0, adiv = 0, vco_div = 0; | ||
439 | int i = 0; | ||
440 | |||
441 | /* Defaults for low freq, low rate */ | ||
442 | state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; | ||
443 | state->VGAarg = cx24123_AGC_vals[0].VGAprogdata; | ||
444 | state->bandselectarg = cx24123_bandselect_vals[0].progdata; | ||
445 | vco_div = cx24123_bandselect_vals[0].VCOdivider; | ||
446 | |||
447 | /* For the given symbolerate, determine the VCA and VGA programming bits */ | ||
448 | for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) | ||
449 | { | ||
450 | if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && | ||
451 | (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { | ||
452 | state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; | ||
453 | state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | /* For the given frequency, determine the bandselect programming bits */ | ||
458 | for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++) | ||
459 | { | ||
460 | if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && | ||
461 | (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) { | ||
462 | state->bandselectarg = cx24123_bandselect_vals[i].progdata; | ||
463 | vco_div = cx24123_bandselect_vals[i].VCOdivider; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /* Determine the N/A dividers for the requested lband freq (in kHz). */ | ||
468 | /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */ | ||
469 | ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff; | ||
470 | adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f; | ||
471 | |||
472 | if (adiv == 0) | ||
473 | adiv++; | ||
474 | |||
475 | /* determine the correct pll frequency values. */ | ||
476 | /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */ | ||
477 | state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14); | ||
478 | state->pllarg |= (ndiv << 5) | adiv; | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * Tuner data is 21 bits long, must be left-aligned in data. | ||
485 | * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip. | ||
486 | */ | ||
487 | static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data) | ||
488 | { | ||
489 | struct cx24123_state *state = fe->demodulator_priv; | ||
490 | unsigned long timeout; | ||
491 | |||
492 | /* align the 21 bytes into to bit23 boundary */ | ||
493 | data = data << 3; | ||
494 | |||
495 | /* Reset the demod pll word length to 0x15 bits */ | ||
496 | cx24123_writereg(state, 0x21, 0x15); | ||
497 | |||
498 | /* write the msb 8 bits, wait for the send to be completed */ | ||
499 | timeout = jiffies + msecs_to_jiffies(40); | ||
500 | cx24123_writereg(state, 0x22, (data >> 16) & 0xff); | ||
501 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | ||
502 | if (time_after(jiffies, timeout)) { | ||
503 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
504 | return -EREMOTEIO; | ||
505 | } | ||
506 | msleep(10); | ||
507 | } | ||
508 | |||
509 | /* send another 8 bytes, wait for the send to be completed */ | ||
510 | timeout = jiffies + msecs_to_jiffies(40); | ||
511 | cx24123_writereg(state, 0x22, (data>>8) & 0xff ); | ||
512 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | ||
513 | if (time_after(jiffies, timeout)) { | ||
514 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
515 | return -EREMOTEIO; | ||
516 | } | ||
517 | msleep(10); | ||
518 | } | ||
519 | |||
520 | /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */ | ||
521 | timeout = jiffies + msecs_to_jiffies(40); | ||
522 | cx24123_writereg(state, 0x22, (data) & 0xff ); | ||
523 | while ((cx24123_readreg(state, 0x20) & 0x80)) { | ||
524 | if (time_after(jiffies, timeout)) { | ||
525 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
526 | return -EREMOTEIO; | ||
527 | } | ||
528 | msleep(10); | ||
529 | } | ||
530 | |||
531 | /* Trigger the demod to configure the tuner */ | ||
532 | cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2); | ||
533 | cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
539 | { | ||
540 | struct cx24123_state *state = fe->demodulator_priv; | ||
541 | |||
542 | if (cx24123_pll_calculate(fe, p) != 0) { | ||
543 | printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); | ||
544 | return -EINVAL; | ||
545 | } | ||
546 | |||
547 | /* Write the new VCO/VGA */ | ||
548 | cx24123_pll_writereg(fe, p, state->VCAarg); | ||
549 | cx24123_pll_writereg(fe, p, state->VGAarg); | ||
550 | |||
551 | /* Write the new bandselect and pll args */ | ||
552 | cx24123_pll_writereg(fe, p, state->bandselectarg); | ||
553 | cx24123_pll_writereg(fe, p, state->pllarg); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int cx24123_initfe(struct dvb_frontend* fe) | ||
559 | { | ||
560 | struct cx24123_state *state = fe->demodulator_priv; | ||
561 | int i; | ||
562 | |||
563 | /* Configure the demod to a good set of defaults */ | ||
564 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) | ||
565 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); | ||
566 | |||
567 | if (state->config->pll_init) | ||
568 | state->config->pll_init(fe); | ||
569 | |||
570 | /* Configure the LNB for 14V */ | ||
571 | if (state->config->use_isl6421) | ||
572 | cx24123_writelnbreg(state, 0x0, 0x2a); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
578 | { | ||
579 | struct cx24123_state *state = fe->demodulator_priv; | ||
580 | u8 val; | ||
581 | |||
582 | switch (state->config->use_isl6421) { | ||
583 | |||
584 | case 1: | ||
585 | |||
586 | val = cx24123_readlnbreg(state, 0x0); | ||
587 | |||
588 | switch (voltage) { | ||
589 | case SEC_VOLTAGE_13: | ||
590 | return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ | ||
591 | case SEC_VOLTAGE_18: | ||
592 | return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ | ||
593 | case SEC_VOLTAGE_OFF: | ||
594 | return cx24123_writelnbreg(state, 0x0, val & 0x30); | ||
595 | default: | ||
596 | return -EINVAL; | ||
597 | }; | ||
598 | |||
599 | case 0: | ||
600 | |||
601 | val = cx24123_readreg(state, 0x29); | ||
602 | |||
603 | switch (voltage) { | ||
604 | case SEC_VOLTAGE_13: | ||
605 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); | ||
606 | if (state->config->enable_lnb_voltage) | ||
607 | state->config->enable_lnb_voltage(fe, 1); | ||
608 | return cx24123_writereg(state, 0x29, val | 0x80); | ||
609 | case SEC_VOLTAGE_18: | ||
610 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); | ||
611 | if (state->config->enable_lnb_voltage) | ||
612 | state->config->enable_lnb_voltage(fe, 1); | ||
613 | return cx24123_writereg(state, 0x29, val & 0x7f); | ||
614 | case SEC_VOLTAGE_OFF: | ||
615 | dprintk("%s: setting voltage off\n", __FUNCTION__); | ||
616 | if (state->config->enable_lnb_voltage) | ||
617 | state->config->enable_lnb_voltage(fe, 0); | ||
618 | return 0; | ||
619 | default: | ||
620 | return -EINVAL; | ||
621 | }; | ||
622 | } | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, | ||
628 | struct dvb_diseqc_master_cmd *cmd) | ||
629 | { | ||
630 | /* fixme: Implement diseqc */ | ||
631 | printk("%s: No support yet\n",__FUNCTION__); | ||
632 | |||
633 | return -ENOTSUPP; | ||
634 | } | ||
635 | |||
636 | static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
637 | { | ||
638 | struct cx24123_state *state = fe->demodulator_priv; | ||
639 | |||
640 | int sync = cx24123_readreg(state, 0x14); | ||
641 | int lock = cx24123_readreg(state, 0x20); | ||
642 | |||
643 | *status = 0; | ||
644 | if (lock & 0x01) | ||
645 | *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; | ||
646 | if (sync & 0x04) | ||
647 | *status |= FE_HAS_VITERBI; | ||
648 | if (sync & 0x08) | ||
649 | *status |= FE_HAS_CARRIER; | ||
650 | if (sync & 0x80) | ||
651 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * Configured to return the measurement of errors in blocks, because no UCBLOCKS value | ||
658 | * is available, so this value doubles up to satisfy both measurements | ||
659 | */ | ||
660 | static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) | ||
661 | { | ||
662 | struct cx24123_state *state = fe->demodulator_priv; | ||
663 | |||
664 | state->lastber = | ||
665 | ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | | ||
666 | (cx24123_readreg(state, 0x1d) << 8 | | ||
667 | cx24123_readreg(state, 0x1e)); | ||
668 | |||
669 | /* Do the signal quality processing here, it's derived from the BER. */ | ||
670 | /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */ | ||
671 | if (state->lastber < 5000) | ||
672 | state->snr = 655*100; | ||
673 | else if ( (state->lastber >= 5000) && (state->lastber < 55000) ) | ||
674 | state->snr = 655*90; | ||
675 | else if ( (state->lastber >= 55000) && (state->lastber < 150000) ) | ||
676 | state->snr = 655*80; | ||
677 | else if ( (state->lastber >= 150000) && (state->lastber < 250000) ) | ||
678 | state->snr = 655*70; | ||
679 | else if ( (state->lastber >= 250000) && (state->lastber < 450000) ) | ||
680 | state->snr = 655*65; | ||
681 | else | ||
682 | state->snr = 0; | ||
683 | |||
684 | *ber = state->lastber; | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | ||
690 | { | ||
691 | struct cx24123_state *state = fe->demodulator_priv; | ||
692 | *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) | ||
698 | { | ||
699 | struct cx24123_state *state = fe->demodulator_priv; | ||
700 | *snr = state->snr; | ||
701 | |||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
706 | { | ||
707 | struct cx24123_state *state = fe->demodulator_priv; | ||
708 | *ucblocks = state->lastber; | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
714 | { | ||
715 | struct cx24123_state *state = fe->demodulator_priv; | ||
716 | |||
717 | if (state->config->set_ts_params) | ||
718 | state->config->set_ts_params(fe, 0); | ||
719 | |||
720 | state->currentfreq=p->frequency; | ||
721 | state->currentsymbolrate = p->u.qpsk.symbol_rate; | ||
722 | |||
723 | cx24123_set_inversion(state, p->inversion); | ||
724 | cx24123_set_fec(state, p->u.qpsk.fec_inner); | ||
725 | cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); | ||
726 | cx24123_pll_tune(fe, p); | ||
727 | |||
728 | /* Enable automatic aquisition and reset cycle */ | ||
729 | cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); | ||
730 | cx24123_writereg(state, 0x00, 0x10); | ||
731 | cx24123_writereg(state, 0x00, 0); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
737 | { | ||
738 | struct cx24123_state *state = fe->demodulator_priv; | ||
739 | |||
740 | if (cx24123_get_inversion(state, &p->inversion) != 0) { | ||
741 | printk("%s: Failed to get inversion status\n",__FUNCTION__); | ||
742 | return -EREMOTEIO; | ||
743 | } | ||
744 | if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { | ||
745 | printk("%s: Failed to get fec status\n",__FUNCTION__); | ||
746 | return -EREMOTEIO; | ||
747 | } | ||
748 | p->frequency = state->currentfreq; | ||
749 | p->u.qpsk.symbol_rate = state->currentsymbolrate; | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
755 | { | ||
756 | struct cx24123_state *state = fe->demodulator_priv; | ||
757 | u8 val; | ||
758 | |||
759 | switch (state->config->use_isl6421) { | ||
760 | case 1: | ||
761 | |||
762 | val = cx24123_readlnbreg(state, 0x0); | ||
763 | |||
764 | switch (tone) { | ||
765 | case SEC_TONE_ON: | ||
766 | return cx24123_writelnbreg(state, 0x0, val | 0x10); | ||
767 | case SEC_TONE_OFF: | ||
768 | return cx24123_writelnbreg(state, 0x0, val & 0x2f); | ||
769 | default: | ||
770 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
771 | return -EINVAL; | ||
772 | } | ||
773 | |||
774 | case 0: | ||
775 | |||
776 | val = cx24123_readreg(state, 0x29); | ||
777 | |||
778 | switch (tone) { | ||
779 | case SEC_TONE_ON: | ||
780 | dprintk("%s: setting tone on\n", __FUNCTION__); | ||
781 | return cx24123_writereg(state, 0x29, val | 0x10); | ||
782 | case SEC_TONE_OFF: | ||
783 | dprintk("%s: setting tone off\n",__FUNCTION__); | ||
784 | return cx24123_writereg(state, 0x29, val & 0xef); | ||
785 | default: | ||
786 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
787 | return -EINVAL; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static void cx24123_release(struct dvb_frontend* fe) | ||
795 | { | ||
796 | struct cx24123_state* state = fe->demodulator_priv; | ||
797 | dprintk("%s\n",__FUNCTION__); | ||
798 | kfree(state); | ||
799 | } | ||
800 | |||
801 | static struct dvb_frontend_ops cx24123_ops; | ||
802 | |||
803 | struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | ||
804 | struct i2c_adapter* i2c) | ||
805 | { | ||
806 | struct cx24123_state* state = NULL; | ||
807 | int ret; | ||
808 | |||
809 | dprintk("%s\n",__FUNCTION__); | ||
810 | |||
811 | /* allocate memory for the internal state */ | ||
812 | state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL); | ||
813 | if (state == NULL) { | ||
814 | printk("Unable to kmalloc\n"); | ||
815 | goto error; | ||
816 | } | ||
817 | |||
818 | /* setup the state */ | ||
819 | state->config = config; | ||
820 | state->i2c = i2c; | ||
821 | memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); | ||
822 | state->lastber = 0; | ||
823 | state->snr = 0; | ||
824 | state->lnbreg = 0; | ||
825 | state->VCAarg = 0; | ||
826 | state->VGAarg = 0; | ||
827 | state->bandselectarg = 0; | ||
828 | state->pllarg = 0; | ||
829 | state->currentfreq = 0; | ||
830 | state->currentsymbolrate = 0; | ||
831 | |||
832 | /* check if the demod is there */ | ||
833 | ret = cx24123_readreg(state, 0x00); | ||
834 | if ((ret != 0xd1) && (ret != 0xe1)) { | ||
835 | printk("Version != d1 or e1\n"); | ||
836 | goto error; | ||
837 | } | ||
838 | |||
839 | /* create dvb_frontend */ | ||
840 | state->frontend.ops = &state->ops; | ||
841 | state->frontend.demodulator_priv = state; | ||
842 | return &state->frontend; | ||
843 | |||
844 | error: | ||
845 | kfree(state); | ||
846 | |||
847 | return NULL; | ||
848 | } | ||
849 | |||
850 | static struct dvb_frontend_ops cx24123_ops = { | ||
851 | |||
852 | .info = { | ||
853 | .name = "Conexant CX24123/CX24109", | ||
854 | .type = FE_QPSK, | ||
855 | .frequency_min = 950000, | ||
856 | .frequency_max = 2150000, | ||
857 | .frequency_stepsize = 1011, /* kHz for QPSK frontends */ | ||
858 | .frequency_tolerance = 29500, | ||
859 | .symbol_rate_min = 1000000, | ||
860 | .symbol_rate_max = 45000000, | ||
861 | .caps = FE_CAN_INVERSION_AUTO | | ||
862 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
863 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
864 | FE_CAN_QPSK | FE_CAN_RECOVER | ||
865 | }, | ||
866 | |||
867 | .release = cx24123_release, | ||
868 | |||
869 | .init = cx24123_initfe, | ||
870 | .set_frontend = cx24123_set_frontend, | ||
871 | .get_frontend = cx24123_get_frontend, | ||
872 | .read_status = cx24123_read_status, | ||
873 | .read_ber = cx24123_read_ber, | ||
874 | .read_signal_strength = cx24123_read_signal_strength, | ||
875 | .read_snr = cx24123_read_snr, | ||
876 | .read_ucblocks = cx24123_read_ucblocks, | ||
877 | .diseqc_send_master_cmd = cx24123_send_diseqc_msg, | ||
878 | .set_tone = cx24123_set_tone, | ||
879 | .set_voltage = cx24123_set_voltage, | ||
880 | }; | ||
881 | |||
882 | module_param(debug, int, 0644); | ||
883 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
884 | |||
885 | MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); | ||
886 | MODULE_AUTHOR("Steven Toth"); | ||
887 | MODULE_LICENSE("GPL"); | ||
888 | |||
889 | EXPORT_SYMBOL(cx24123_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h new file mode 100644 index 000000000000..0c922b5e9263 --- /dev/null +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef CX24123_H | ||
22 | #define CX24123_H | ||
23 | |||
24 | #include <linux/dvb/frontend.h> | ||
25 | |||
26 | struct cx24123_config | ||
27 | { | ||
28 | /* the demodulator's i2c address */ | ||
29 | u8 demod_address; | ||
30 | |||
31 | /* | ||
32 | cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip | ||
33 | for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits | ||
34 | from register 0x29 of the CX24123 demodulator | ||
35 | */ | ||
36 | int use_isl6421; | ||
37 | |||
38 | /* PLL maintenance */ | ||
39 | int (*pll_init)(struct dvb_frontend* fe); | ||
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
41 | |||
42 | /* Need to set device param for start_dma */ | ||
43 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | ||
44 | |||
45 | void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); | ||
46 | }; | ||
47 | |||
48 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | ||
49 | struct i2c_adapter* i2c); | ||
50 | |||
51 | #endif /* CX24123_H */ | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index f857b869616c..a3d57ce9dd12 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -107,18 +107,19 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { | |||
107 | }; | 107 | }; |
108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); | 108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); |
109 | 109 | ||
110 | struct dvb_pll_desc dvb_pll_thomson_dtt7611 = { | 110 | struct dvb_pll_desc dvb_pll_thomson_dtt761x = { |
111 | .name = "Thomson dtt7611", | 111 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
112 | .min = 44000000, | 112 | .name = "Thomson dtt761x", |
113 | .max = 958000000, | 113 | .min = 57000000, |
114 | .max = 863000000, | ||
114 | .count = 3, | 115 | .count = 3, |
115 | .entries = { | 116 | .entries = { |
116 | { 157250000, 44000000, 62500, 0x8e, 0x39 }, | 117 | { 147000000, 44000000, 62500, 0x8e, 0x39 }, |
117 | { 454000000, 44000000, 62500, 0x8e, 0x3a }, | 118 | { 417000000, 44000000, 62500, 0x8e, 0x3a }, |
118 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 119 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, |
119 | }, | 120 | }, |
120 | }; | 121 | }; |
121 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7611); | 122 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); |
122 | 123 | ||
123 | struct dvb_pll_desc dvb_pll_unknown_1 = { | 124 | struct dvb_pll_desc dvb_pll_unknown_1 = { |
124 | .name = "unknown 1", /* used by dntv live dvb-t */ | 125 | .name = "unknown 1", /* used by dntv live dvb-t */ |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 497d31dcf41e..24d4d2e9acd8 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -25,7 +25,7 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; | |||
25 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; | 25 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; |
26 | extern struct dvb_pll_desc dvb_pll_lg_z201; | 26 | extern struct dvb_pll_desc dvb_pll_lg_z201; |
27 | extern struct dvb_pll_desc dvb_pll_microtune_4042; | 27 | extern struct dvb_pll_desc dvb_pll_microtune_4042; |
28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7611; | 28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt761x; |
29 | extern struct dvb_pll_desc dvb_pll_unknown_1; | 29 | extern struct dvb_pll_desc dvb_pll_unknown_1; |
30 | 30 | ||
31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | 31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; |
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index cb5301865d07..9d214643b87a 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * DViCO FusionHDTV 3 Gold-T | 27 | * DViCO FusionHDTV 3 Gold-T |
28 | * DViCO FusionHDTV 5 Gold | 28 | * DViCO FusionHDTV 5 Gold |
29 | * DViCO FusionHDTV 5 Lite | 29 | * DViCO FusionHDTV 5 Lite |
30 | * DViCO FusionHDTV 5 USB Gold | ||
30 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) | 31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) |
31 | * | 32 | * |
32 | * TODO: | 33 | * TODO: |
@@ -402,6 +403,8 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, | |||
402 | state->config->pll_set(fe, param); | 403 | state->config->pll_set(fe, param); |
403 | 404 | ||
404 | /* Keep track of the new frequency */ | 405 | /* Keep track of the new frequency */ |
406 | /* FIXME this is the wrong way to do this... */ | ||
407 | /* The tuner is shared with the video4linux analog API */ | ||
405 | state->current_frequency = param->frequency; | 408 | state->current_frequency = param->frequency; |
406 | 409 | ||
407 | lgdt330x_SwReset(state); | 410 | lgdt330x_SwReset(state); |
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c index 52c416043a62..4f263e65ba14 100644 --- a/drivers/media/dvb/frontends/nxt2002.c +++ b/drivers/media/dvb/frontends/nxt2002.c | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * This driver needs external firmware. Please use the command | 23 | * This driver needs external firmware. Please use the command |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to |
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
26 | */ | 27 | */ |
27 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" | 28 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" |
28 | #define CRC_CCIT_MASK 0x1021 | 29 | #define CRC_CCIT_MASK 0x1021 |
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a458a3bfff70..a16eeba0020d 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c | |||
@@ -574,11 +574,11 @@ static struct dvb_frontend_ops nxt6000_ops = { | |||
574 | .symbol_rate_max = 9360000, /* FIXME */ | 574 | .symbol_rate_max = 9360000, /* FIXME */ |
575 | .symbol_rate_tolerance = 4000, | 575 | .symbol_rate_tolerance = 4000, |
576 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 576 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
577 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | 577 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | |
578 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | 578 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | |
579 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | 579 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | |
580 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | 580 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | |
581 | FE_CAN_HIERARCHY_AUTO, | 581 | FE_CAN_HIERARCHY_AUTO, |
582 | }, | 582 | }, |
583 | 583 | ||
584 | .release = nxt6000_release, | 584 | .release = nxt6000_release, |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 531f76246e5f..7c3aed1f546b 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -25,7 +25,8 @@ | |||
25 | /* | 25 | /* |
26 | * This driver needs external firmware. Please use the command | 26 | * This driver needs external firmware. Please use the command |
27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to | 27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to |
28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
29 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
29 | */ | 30 | */ |
30 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" | 31 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" |
31 | 32 | ||
@@ -112,7 +113,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe, | |||
112 | u8 tudata[585]; | 113 | u8 tudata[585]; |
113 | int i; | 114 | int i; |
114 | 115 | ||
115 | dprintk("Firmware is %d bytes\n",fw->size); | 116 | dprintk("Firmware is %zd bytes\n",fw->size); |
116 | 117 | ||
117 | /* Get eprom data */ | 118 | /* Get eprom data */ |
118 | tudata[0] = 17; | 119 | tudata[0] = 17; |
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 18715091aed8..d69477596921 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c | |||
@@ -521,8 +521,8 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, | |||
521 | 521 | ||
522 | case FEC_3_4: | 522 | case FEC_3_4: |
523 | s5h1420_writereg(state, 0x30, 0x04); | 523 | s5h1420_writereg(state, 0x30, 0x04); |
524 | s5h1420_writereg(state, 0x31, 0x12 | inversion); | 524 | s5h1420_writereg(state, 0x31, 0x12 | inversion); |
525 | break; | 525 | break; |
526 | 526 | ||
527 | case FEC_5_6: | 527 | case FEC_5_6: |
528 | s5h1420_writereg(state, 0x30, 0x08); | 528 | s5h1420_writereg(state, 0x30, 0x08); |
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index fc06cd6b46c3..73829e647e50 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * This driver needs external firmware. Please use the command | 23 | * This driver needs external firmware. Please use the command |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to |
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
26 | */ | 27 | */ |
27 | #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" | 28 | #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" |
28 | 29 | ||
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index e3b665782243..eb8a602198ca 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c | |||
@@ -5,7 +5,8 @@ | |||
5 | /* | 5 | /* |
6 | * This driver needs external firmware. Please use the command | 6 | * This driver needs external firmware. Please use the command |
7 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to | 7 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to |
8 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 8 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
9 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
9 | */ | 10 | */ |
10 | #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" | 11 | #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" |
11 | 12 | ||
@@ -581,7 +582,7 @@ static struct dvb_frontend_ops sp887x_ops = { | |||
581 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 582 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
582 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 583 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
583 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | | 584 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | |
584 | FE_CAN_RECOVER | 585 | FE_CAN_RECOVER |
585 | }, | 586 | }, |
586 | 587 | ||
587 | .release = sp887x_release, | 588 | .release = sp887x_release, |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 177d71d56b67..5bcd00f792e6 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -131,6 +131,13 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len | |||
131 | return ret == 2 ? 0 : ret; | 131 | return ret == 2 ? 0 : ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | int stv0299_enable_plli2c (struct dvb_frontend* fe) | ||
135 | { | ||
136 | struct stv0299_state* state = fe->demodulator_priv; | ||
137 | |||
138 | return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
139 | } | ||
140 | |||
134 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) | 141 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) |
135 | { | 142 | { |
136 | dprintk ("%s\n", __FUNCTION__); | 143 | dprintk ("%s\n", __FUNCTION__); |
@@ -387,7 +394,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
387 | }; | 394 | }; |
388 | } | 395 | } |
389 | 396 | ||
390 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | 397 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) |
391 | { | 398 | { |
392 | struct stv0299_state* state = fe->demodulator_priv; | 399 | struct stv0299_state* state = fe->demodulator_priv; |
393 | u8 reg0x08; | 400 | u8 reg0x08; |
@@ -407,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | |||
407 | 414 | ||
408 | cmd = cmd << 1; | 415 | cmd = cmd << 1; |
409 | if (debug_legacy_dish_switch) | 416 | if (debug_legacy_dish_switch) |
410 | printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); | 417 | printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd); |
411 | 418 | ||
412 | do_gettimeofday (&nexttime); | 419 | do_gettimeofday (&nexttime); |
413 | if (debug_legacy_dish_switch) | 420 | if (debug_legacy_dish_switch) |
@@ -717,5 +724,6 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " | |||
717 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); | 724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); |
718 | MODULE_LICENSE("GPL"); | 725 | MODULE_LICENSE("GPL"); |
719 | 726 | ||
727 | EXPORT_SYMBOL(stv0299_enable_plli2c); | ||
720 | EXPORT_SYMBOL(stv0299_writereg); | 728 | EXPORT_SYMBOL(stv0299_writereg); |
721 | EXPORT_SYMBOL(stv0299_attach); | 729 | EXPORT_SYMBOL(stv0299_attach); |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 9af3d71c89db..32c87b4c2f13 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -94,6 +94,7 @@ struct stv0299_config | |||
94 | }; | 94 | }; |
95 | 95 | ||
96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); | 96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); |
97 | extern int stv0299_enable_plli2c (struct dvb_frontend* fe); | ||
97 | 98 | ||
98 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | 99 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, |
99 | struct i2c_adapter* i2c); | 100 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 425cd19136fe..21255cac9793 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -95,7 +95,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | |||
95 | u8 b0 [] = { reg }; | 95 | u8 b0 [] = { reg }; |
96 | u8 b1 [] = { 0 }; | 96 | u8 b1 [] = { 0 }; |
97 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | 97 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, |
98 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 98 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; |
99 | int ret; | 99 | int ret; |
100 | 100 | ||
101 | ret = i2c_transfer (state->i2c, msg, 2); | 101 | ret = i2c_transfer (state->i2c, msg, 2); |
@@ -434,7 +434,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
434 | .frequency_max = 858000000, | 434 | .frequency_max = 858000000, |
435 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ | 435 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ |
436 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ | 436 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ |
437 | #if 0 | 437 | #if 0 |
438 | .frequency_tolerance = ???, | 438 | .frequency_tolerance = ???, |
439 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ | 439 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ |
440 | #endif | 440 | #endif |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index dd02aff467fe..c63e9a5084eb 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -23,7 +23,8 @@ | |||
23 | * This driver needs external firmware. Please use the commands | 23 | * This driver needs external firmware. Please use the commands |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", |
25 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to | 25 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to |
26 | * download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 26 | * download/extract them, and then copy them to /usr/lib/hotplug/firmware |
27 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
27 | */ | 28 | */ |
28 | #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" | 29 | #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" |
29 | #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" | 30 | #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" |
@@ -271,32 +272,57 @@ static int tda10045h_set_bandwidth(struct tda1004x_state *state, | |||
271 | static int tda10046h_set_bandwidth(struct tda1004x_state *state, | 272 | static int tda10046h_set_bandwidth(struct tda1004x_state *state, |
272 | fe_bandwidth_t bandwidth) | 273 | fe_bandwidth_t bandwidth) |
273 | { | 274 | { |
274 | static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e }; | 275 | static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; |
275 | static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 }; | 276 | static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; |
276 | static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd }; | 277 | static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d }; |
277 | 278 | ||
279 | static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 }; | ||
280 | static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab }; | ||
281 | static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 }; | ||
282 | int tda10046_clk53m; | ||
283 | |||
284 | if ((state->config->if_freq == TDA10046_FREQ_045) || | ||
285 | (state->config->if_freq == TDA10046_FREQ_052)) | ||
286 | tda10046_clk53m = 0; | ||
287 | else | ||
288 | tda10046_clk53m = 1; | ||
278 | switch (bandwidth) { | 289 | switch (bandwidth) { |
279 | case BANDWIDTH_6_MHZ: | 290 | case BANDWIDTH_6_MHZ: |
280 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); | 291 | if (tda10046_clk53m) |
292 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, | ||
293 | sizeof(bandwidth_6mhz_53M)); | ||
294 | else | ||
295 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M, | ||
296 | sizeof(bandwidth_6mhz_48M)); | ||
281 | if (state->config->if_freq == TDA10046_FREQ_045) { | 297 | if (state->config->if_freq == TDA10046_FREQ_045) { |
282 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09); | 298 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); |
283 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f); | 299 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab); |
284 | } | 300 | } |
285 | break; | 301 | break; |
286 | 302 | ||
287 | case BANDWIDTH_7_MHZ: | 303 | case BANDWIDTH_7_MHZ: |
288 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); | 304 | if (tda10046_clk53m) |
305 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, | ||
306 | sizeof(bandwidth_7mhz_53M)); | ||
307 | else | ||
308 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M, | ||
309 | sizeof(bandwidth_7mhz_48M)); | ||
289 | if (state->config->if_freq == TDA10046_FREQ_045) { | 310 | if (state->config->if_freq == TDA10046_FREQ_045) { |
290 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); | 311 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); |
291 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79); | 312 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); |
292 | } | 313 | } |
293 | break; | 314 | break; |
294 | 315 | ||
295 | case BANDWIDTH_8_MHZ: | 316 | case BANDWIDTH_8_MHZ: |
296 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); | 317 | if (tda10046_clk53m) |
318 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, | ||
319 | sizeof(bandwidth_8mhz_53M)); | ||
320 | else | ||
321 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M, | ||
322 | sizeof(bandwidth_8mhz_48M)); | ||
297 | if (state->config->if_freq == TDA10046_FREQ_045) { | 323 | if (state->config->if_freq == TDA10046_FREQ_045) { |
298 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); | 324 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); |
299 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); | 325 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55); |
300 | } | 326 | } |
301 | break; | 327 | break; |
302 | 328 | ||
@@ -418,9 +444,22 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
418 | static void tda10046_init_plls(struct dvb_frontend* fe) | 444 | static void tda10046_init_plls(struct dvb_frontend* fe) |
419 | { | 445 | { |
420 | struct tda1004x_state* state = fe->demodulator_priv; | 446 | struct tda1004x_state* state = fe->demodulator_priv; |
447 | int tda10046_clk53m; | ||
448 | |||
449 | if ((state->config->if_freq == TDA10046_FREQ_045) || | ||
450 | (state->config->if_freq == TDA10046_FREQ_052)) | ||
451 | tda10046_clk53m = 0; | ||
452 | else | ||
453 | tda10046_clk53m = 1; | ||
421 | 454 | ||
422 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); | 455 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); |
423 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10 | 456 | if(tda10046_clk53m) { |
457 | printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n"); | ||
458 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8 | ||
459 | } else { | ||
460 | printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n"); | ||
461 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 | ||
462 | } | ||
424 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { | 463 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { |
425 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); | 464 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); |
426 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 | 465 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 |
@@ -428,26 +467,32 @@ static void tda10046_init_plls(struct dvb_frontend* fe) | |||
428 | dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); | 467 | dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); |
429 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 | 468 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 |
430 | } | 469 | } |
431 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); | 470 | if(tda10046_clk53m) |
471 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67); | ||
472 | else | ||
473 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72); | ||
474 | /* Note clock frequency is handled implicitly */ | ||
432 | switch (state->config->if_freq) { | 475 | switch (state->config->if_freq) { |
433 | case TDA10046_FREQ_3617: | ||
434 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | ||
435 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); | ||
436 | break; | ||
437 | case TDA10046_FREQ_3613: | ||
438 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | ||
439 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13); | ||
440 | break; | ||
441 | case TDA10046_FREQ_045: | 476 | case TDA10046_FREQ_045: |
442 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); | 477 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); |
443 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); | 478 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); |
444 | break; | 479 | break; |
445 | case TDA10046_FREQ_052: | 480 | case TDA10046_FREQ_052: |
446 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); | 481 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); |
447 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06); | 482 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7); |
483 | break; | ||
484 | case TDA10046_FREQ_3617: | ||
485 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); | ||
486 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59); | ||
487 | break; | ||
488 | case TDA10046_FREQ_3613: | ||
489 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); | ||
490 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); | ||
448 | break; | 491 | break; |
449 | } | 492 | } |
450 | tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz | 493 | tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz |
494 | /* let the PLLs settle */ | ||
495 | msleep(120); | ||
451 | } | 496 | } |
452 | 497 | ||
453 | static int tda10046_fwupload(struct dvb_frontend* fe) | 498 | static int tda10046_fwupload(struct dvb_frontend* fe) |
@@ -462,13 +507,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
462 | /* let the clocks recover from sleep */ | 507 | /* let the clocks recover from sleep */ |
463 | msleep(5); | 508 | msleep(5); |
464 | 509 | ||
510 | /* The PLLs need to be reprogrammed after sleep */ | ||
511 | tda10046_init_plls(fe); | ||
512 | |||
465 | /* don't re-upload unless necessary */ | 513 | /* don't re-upload unless necessary */ |
466 | if (tda1004x_check_upload_ok(state) == 0) | 514 | if (tda1004x_check_upload_ok(state) == 0) |
467 | return 0; | 515 | return 0; |
468 | 516 | ||
469 | /* set parameters */ | ||
470 | tda10046_init_plls(fe); | ||
471 | |||
472 | if (state->config->request_firmware != NULL) { | 517 | if (state->config->request_firmware != NULL) { |
473 | /* request the firmware, this will block until someone uploads it */ | 518 | /* request the firmware, this will block until someone uploads it */ |
474 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); | 519 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); |
@@ -484,7 +529,6 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
484 | return ret; | 529 | return ret; |
485 | } else { | 530 | } else { |
486 | /* boot from firmware eeprom */ | 531 | /* boot from firmware eeprom */ |
487 | /* Hac Note: we might need to do some GPIO Magic here */ | ||
488 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); | 532 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); |
489 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | 533 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); |
490 | msleep(300); | 534 | msleep(300); |
@@ -606,10 +650,9 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
606 | 650 | ||
607 | // tda setup | 651 | // tda setup |
608 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 652 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
609 | tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream | 653 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream |
610 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer | 654 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer |
611 | 655 | ||
612 | tda10046_init_plls(fe); | ||
613 | switch (state->config->agc_config) { | 656 | switch (state->config->agc_config) { |
614 | case TDA10046_AGC_DEFAULT: | 657 | case TDA10046_AGC_DEFAULT: |
615 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup | 658 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup |
@@ -626,25 +669,22 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
626 | case TDA10046_AGC_TDA827X: | 669 | case TDA10046_AGC_TDA827X: |
627 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | 670 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup |
628 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | 671 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold |
629 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize | 672 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize |
630 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 673 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities |
631 | break; | 674 | break; |
632 | } | 675 | } |
676 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); | ||
633 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on | 677 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on |
634 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } | 678 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } |
635 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values | 679 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values |
636 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } | 680 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } |
637 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } | 681 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } |
638 | tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 | 682 | tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1 |
639 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits | 683 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits |
640 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config | 684 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config |
641 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config | 685 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config |
642 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | 686 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); |
643 | 687 | ||
644 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup | ||
645 | tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config | ||
646 | tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select | ||
647 | |||
648 | state->initialised = 1; | 688 | state->initialised = 1; |
649 | return 0; | 689 | return 0; |
650 | } | 690 | } |
@@ -686,9 +726,9 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
686 | 726 | ||
687 | // Set standard params.. or put them to auto | 727 | // Set standard params.. or put them to auto |
688 | if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || | 728 | if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || |
689 | (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || | 729 | (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || |
690 | (fe_params->u.ofdm.constellation == QAM_AUTO) || | 730 | (fe_params->u.ofdm.constellation == QAM_AUTO) || |
691 | (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { | 731 | (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { |
692 | tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto | 732 | tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto |
693 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits | 733 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits |
694 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits | 734 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits |
@@ -851,6 +891,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
851 | static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) | 891 | static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) |
852 | { | 892 | { |
853 | struct tda1004x_state* state = fe->demodulator_priv; | 893 | struct tda1004x_state* state = fe->demodulator_priv; |
894 | |||
854 | dprintk("%s\n", __FUNCTION__); | 895 | dprintk("%s\n", __FUNCTION__); |
855 | 896 | ||
856 | // inversion status | 897 | // inversion status |
@@ -875,16 +916,18 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
875 | break; | 916 | break; |
876 | } | 917 | } |
877 | break; | 918 | break; |
878 | |||
879 | case TDA1004X_DEMOD_TDA10046: | 919 | case TDA1004X_DEMOD_TDA10046: |
880 | switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { | 920 | switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { |
881 | case 0x60: | 921 | case 0x5c: |
922 | case 0x54: | ||
882 | fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; | 923 | fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; |
883 | break; | 924 | break; |
884 | case 0x6e: | 925 | case 0x6a: |
926 | case 0x60: | ||
885 | fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; | 927 | fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; |
886 | break; | 928 | break; |
887 | case 0x80: | 929 | case 0x7b: |
930 | case 0x70: | ||
888 | fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | 931 | fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; |
889 | break; | 932 | break; |
890 | } | 933 | } |
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig index f02842be0d60..84f8f9f52869 100644 --- a/drivers/media/dvb/pluto2/Kconfig +++ b/drivers/media/dvb/pluto2/Kconfig | |||
@@ -8,7 +8,7 @@ config DVB_PLUTO2 | |||
8 | Support for PCI cards based on the Pluto2 FPGA like the Satelco | 8 | Support for PCI cards based on the Pluto2 FPGA like the Satelco |
9 | Easywatch Mobile Terrestrial DVB-T Receiver. | 9 | Easywatch Mobile Terrestrial DVB-T Receiver. |
10 | 10 | ||
11 | Since these cards have no MPEG decoder onboard, they transmit | 11 | Since these cards have no MPEG decoder onboard, they transmit |
12 | only compressed MPEG data over the PCI bus, so you need | 12 | only compressed MPEG data over the PCI bus, so you need |
13 | an external software decoder to watch TV on your computer. | 13 | an external software decoder to watch TV on your computer. |
14 | 14 | ||
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index fa5034a9ecf5..5b2aadb8385c 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -18,9 +18,10 @@ config DVB_AV7110 | |||
18 | This driver only supports the fullfeatured cards with | 18 | This driver only supports the fullfeatured cards with |
19 | onboard MPEG2 decoder. | 19 | onboard MPEG2 decoder. |
20 | 20 | ||
21 | This driver needs an external firmware. Please use the script | 21 | This driver needs an external firmware. Please use the script |
22 | "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to | 22 | "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to |
23 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 23 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
24 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
24 | 25 | ||
25 | Say Y if you own such a card and want to use it. | 26 | Say Y if you own such a card and want to use it. |
26 | 27 | ||
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index 825ab1c38a4f..a690730ac39d 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile | |||
@@ -16,7 +16,7 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | |||
16 | hostprogs-y := fdump | 16 | hostprogs-y := fdump |
17 | 17 | ||
18 | ifdef CONFIG_DVB_AV7110_FIRMWARE | 18 | ifdef CONFIG_DVB_AV7110_FIRMWARE |
19 | $(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h | 19 | $(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h |
20 | 20 | ||
21 | $(obj)/av7110_firm.h: | 21 | $(obj)/av7110_firm.h: |
22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ | 22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 7dae91e5863c..8ce4146f55f1 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -133,7 +133,13 @@ static void init_av7110_av(struct av7110 *av7110) | |||
133 | /* remaining inits according to card and frontend type */ | 133 | /* remaining inits according to card and frontend type */ |
134 | av7110->analog_tuner_flags = 0; | 134 | av7110->analog_tuner_flags = 0; |
135 | av7110->current_input = 0; | 135 | av7110->current_input = 0; |
136 | if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | 136 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) { |
137 | printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n", | ||
138 | av7110->dvb_adapter.num); | ||
139 | av7110->adac_type = DVB_ADAC_MSP34x5; | ||
140 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on | ||
141 | } | ||
142 | else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | ||
137 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", | 143 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", |
138 | av7110->dvb_adapter.num); | 144 | av7110->dvb_adapter.num); |
139 | av7110->adac_type = DVB_ADAC_CRYSTAL; | 145 | av7110->adac_type = DVB_ADAC_CRYSTAL; |
@@ -156,10 +162,10 @@ static void init_av7110_av(struct av7110 *av7110) | |||
156 | else { | 162 | else { |
157 | av7110->adac_type = adac; | 163 | av7110->adac_type = adac; |
158 | printk("dvb-ttpci: adac type set to %d @ card %d\n", | 164 | printk("dvb-ttpci: adac type set to %d @ card %d\n", |
159 | av7110->dvb_adapter.num, av7110->adac_type); | 165 | av7110->adac_type, av7110->dvb_adapter.num); |
160 | } | 166 | } |
161 | 167 | ||
162 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { | 168 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) { |
163 | // switch DVB SCART on | 169 | // switch DVB SCART on |
164 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); | 170 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); |
165 | if (ret < 0) | 171 | if (ret < 0) |
@@ -190,17 +196,15 @@ static void recover_arm(struct av7110 *av7110) | |||
190 | 196 | ||
191 | av7110_bootarm(av7110); | 197 | av7110_bootarm(av7110); |
192 | msleep(100); | 198 | msleep(100); |
193 | restart_feeds(av7110); | ||
194 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); | ||
195 | } | ||
196 | 199 | ||
197 | static void arm_error(struct av7110 *av7110) | 200 | init_av7110_av(av7110); |
198 | { | 201 | |
199 | dprintk(4, "%p\n",av7110); | 202 | /* card-specific recovery */ |
203 | if (av7110->recover) | ||
204 | av7110->recover(av7110); | ||
200 | 205 | ||
201 | av7110->arm_errors++; | 206 | restart_feeds(av7110); |
202 | av7110->arm_ready = 0; | 207 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); |
203 | recover_arm(av7110); | ||
204 | } | 208 | } |
205 | 209 | ||
206 | static void av7110_arm_sync(struct av7110 *av7110) | 210 | static void av7110_arm_sync(struct av7110 *av7110) |
@@ -240,26 +244,22 @@ static int arm_thread(void *data) | |||
240 | 244 | ||
241 | if (down_interruptible(&av7110->dcomlock)) | 245 | if (down_interruptible(&av7110->dcomlock)) |
242 | break; | 246 | break; |
243 | |||
244 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); | 247 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); |
245 | up(&av7110->dcomlock); | 248 | up(&av7110->dcomlock); |
246 | 249 | ||
247 | if (newloops == av7110->arm_loops) { | 250 | if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { |
248 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", | 251 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", |
249 | av7110->dvb_adapter.num); | 252 | av7110->dvb_adapter.num); |
250 | 253 | ||
251 | arm_error(av7110); | 254 | recover_arm(av7110); |
252 | av7710_set_video_mode(av7110, vidmode); | ||
253 | |||
254 | init_av7110_av(av7110); | ||
255 | 255 | ||
256 | if (down_interruptible(&av7110->dcomlock)) | 256 | if (down_interruptible(&av7110->dcomlock)) |
257 | break; | 257 | break; |
258 | |||
259 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; | 258 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; |
260 | up(&av7110->dcomlock); | 259 | up(&av7110->dcomlock); |
261 | } | 260 | } |
262 | av7110->arm_loops = newloops; | 261 | av7110->arm_loops = newloops; |
262 | av7110->arm_errors = 0; | ||
263 | } | 263 | } |
264 | 264 | ||
265 | av7110->arm_thread = NULL; | 265 | av7110->arm_thread = NULL; |
@@ -510,10 +510,6 @@ static void gpioirq(unsigned long data) | |||
510 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | 510 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); |
511 | 511 | ||
512 | av7110->video_size.h = h_ar & 0xfff; | 512 | av7110->video_size.h = h_ar & 0xfff; |
513 | dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", | ||
514 | av7110->video_size.w, | ||
515 | av7110->video_size.h, | ||
516 | av7110->video_size.aspect_ratio); | ||
517 | 513 | ||
518 | event.type = VIDEO_EVENT_SIZE_CHANGED; | 514 | event.type = VIDEO_EVENT_SIZE_CHANGED; |
519 | event.u.size.w = av7110->video_size.w; | 515 | event.u.size.w = av7110->video_size.w; |
@@ -535,6 +531,11 @@ static void gpioirq(unsigned long data) | |||
535 | event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; | 531 | event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; |
536 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; | 532 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; |
537 | } | 533 | } |
534 | |||
535 | dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", | ||
536 | av7110->video_size.w, av7110->video_size.h, | ||
537 | av7110->video_size.aspect_ratio); | ||
538 | |||
538 | dvb_video_add_event(av7110, &event); | 539 | dvb_video_add_event(av7110, &event); |
539 | break; | 540 | break; |
540 | } | 541 | } |
@@ -714,6 +715,8 @@ static struct dvb_device dvbdev_osd = { | |||
714 | static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 715 | static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
715 | u16 subpid, u16 pcrpid) | 716 | u16 subpid, u16 pcrpid) |
716 | { | 717 | { |
718 | u16 aflags = 0; | ||
719 | |||
717 | dprintk(4, "%p\n", av7110); | 720 | dprintk(4, "%p\n", av7110); |
718 | 721 | ||
719 | if (vpid == 0x1fff || apid == 0x1fff || | 722 | if (vpid == 0x1fff || apid == 0x1fff || |
@@ -725,8 +728,11 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | |||
725 | av7110->pids[DMX_PES_PCR] = 0; | 728 | av7110->pids[DMX_PES_PCR] = 0; |
726 | } | 729 | } |
727 | 730 | ||
728 | return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5, | 731 | if (av7110->audiostate.bypass_mode) |
729 | pcrpid, vpid, apid, ttpid, subpid); | 732 | aflags |= 0x8000; |
733 | |||
734 | return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6, | ||
735 | pcrpid, vpid, apid, ttpid, subpid, aflags); | ||
730 | } | 736 | } |
731 | 737 | ||
732 | int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 738 | int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
@@ -1043,7 +1049,7 @@ static void restart_feeds(struct av7110 *av7110) | |||
1043 | struct dvb_demux *dvbdmx = &av7110->demux; | 1049 | struct dvb_demux *dvbdmx = &av7110->demux; |
1044 | struct dvb_demux_feed *feed; | 1050 | struct dvb_demux_feed *feed; |
1045 | int mode; | 1051 | int mode; |
1046 | int i; | 1052 | int i, j; |
1047 | 1053 | ||
1048 | dprintk(4, "%p\n", av7110); | 1054 | dprintk(4, "%p\n", av7110); |
1049 | 1055 | ||
@@ -1051,10 +1057,21 @@ static void restart_feeds(struct av7110 *av7110) | |||
1051 | av7110->playing = 0; | 1057 | av7110->playing = 0; |
1052 | av7110->rec_mode = 0; | 1058 | av7110->rec_mode = 0; |
1053 | 1059 | ||
1054 | for (i = 0; i < dvbdmx->filternum; i++) { | 1060 | for (i = 0; i < dvbdmx->feednum; i++) { |
1055 | feed = &dvbdmx->feed[i]; | 1061 | feed = &dvbdmx->feed[i]; |
1056 | if (feed->state == DMX_STATE_GO) | 1062 | if (feed->state == DMX_STATE_GO) { |
1063 | if (feed->type == DMX_TYPE_SEC) { | ||
1064 | for (j = 0; j < dvbdmx->filternum; j++) { | ||
1065 | if (dvbdmx->filter[j].type != DMX_TYPE_SEC) | ||
1066 | continue; | ||
1067 | if (dvbdmx->filter[j].filter.parent != &feed->feed.sec) | ||
1068 | continue; | ||
1069 | if (dvbdmx->filter[j].state == DMX_STATE_GO) | ||
1070 | dvbdmx->filter[j].state = DMX_STATE_READY; | ||
1071 | } | ||
1072 | } | ||
1057 | av7110_start_feed(feed); | 1073 | av7110_start_feed(feed); |
1074 | } | ||
1058 | } | 1075 | } |
1059 | 1076 | ||
1060 | if (mode) | 1077 | if (mode) |
@@ -1483,9 +1500,9 @@ static int get_firmware(struct av7110* av7110) | |||
1483 | if (ret == -ENOENT) { | 1500 | if (ret == -ENOENT) { |
1484 | printk(KERN_ERR "dvb-ttpci: could not load firmware," | 1501 | printk(KERN_ERR "dvb-ttpci: could not load firmware," |
1485 | " file not found: dvb-ttpci-01.fw\n"); | 1502 | " file not found: dvb-ttpci-01.fw\n"); |
1486 | printk(KERN_ERR "dvb-ttpci: usually this should be in" | 1503 | printk(KERN_ERR "dvb-ttpci: usually this should be in " |
1487 | " /usr/lib/hotplug/firmware\n"); | 1504 | "/usr/lib/hotplug/firmware or /lib/firmware\n"); |
1488 | printk(KERN_ERR "dvb-ttpci: and can be downloaded here" | 1505 | printk(KERN_ERR "dvb-ttpci: and can be downloaded from" |
1489 | " http://www.linuxtv.org/download/dvb/firmware/\n"); | 1506 | " http://www.linuxtv.org/download/dvb/firmware/\n"); |
1490 | } else | 1507 | } else |
1491 | printk(KERN_ERR "dvb-ttpci: cannot request firmware" | 1508 | printk(KERN_ERR "dvb-ttpci: cannot request firmware" |
@@ -2110,8 +2127,10 @@ static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_p | |||
2110 | struct av7110* av7110 = fe->dvb->priv; | 2127 | struct av7110* av7110 = fe->dvb->priv; |
2111 | 2128 | ||
2112 | int ret = av7110_fe_lock_fix(av7110, 0); | 2129 | int ret = av7110_fe_lock_fix(av7110, 0); |
2113 | if (!ret) | 2130 | if (!ret) { |
2131 | av7110->saved_fe_params = *params; | ||
2114 | ret = av7110->fe_set_frontend(fe, params); | 2132 | ret = av7110->fe_set_frontend(fe, params); |
2133 | } | ||
2115 | return ret; | 2134 | return ret; |
2116 | } | 2135 | } |
2117 | 2136 | ||
@@ -2153,8 +2172,10 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, | |||
2153 | struct av7110* av7110 = fe->dvb->priv; | 2172 | struct av7110* av7110 = fe->dvb->priv; |
2154 | 2173 | ||
2155 | int ret = av7110_fe_lock_fix(av7110, 0); | 2174 | int ret = av7110_fe_lock_fix(av7110, 0); |
2156 | if (!ret) | 2175 | if (!ret) { |
2176 | av7110->saved_master_cmd = *cmd; | ||
2157 | ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); | 2177 | ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); |
2178 | } | ||
2158 | return ret; | 2179 | return ret; |
2159 | } | 2180 | } |
2160 | 2181 | ||
@@ -2163,8 +2184,10 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_ | |||
2163 | struct av7110* av7110 = fe->dvb->priv; | 2184 | struct av7110* av7110 = fe->dvb->priv; |
2164 | 2185 | ||
2165 | int ret = av7110_fe_lock_fix(av7110, 0); | 2186 | int ret = av7110_fe_lock_fix(av7110, 0); |
2166 | if (!ret) | 2187 | if (!ret) { |
2188 | av7110->saved_minicmd = minicmd; | ||
2167 | ret = av7110->fe_diseqc_send_burst(fe, minicmd); | 2189 | ret = av7110->fe_diseqc_send_burst(fe, minicmd); |
2190 | } | ||
2168 | return ret; | 2191 | return ret; |
2169 | } | 2192 | } |
2170 | 2193 | ||
@@ -2173,8 +2196,10 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
2173 | struct av7110* av7110 = fe->dvb->priv; | 2196 | struct av7110* av7110 = fe->dvb->priv; |
2174 | 2197 | ||
2175 | int ret = av7110_fe_lock_fix(av7110, 0); | 2198 | int ret = av7110_fe_lock_fix(av7110, 0); |
2176 | if (!ret) | 2199 | if (!ret) { |
2200 | av7110->saved_tone = tone; | ||
2177 | ret = av7110->fe_set_tone(fe, tone); | 2201 | ret = av7110->fe_set_tone(fe, tone); |
2202 | } | ||
2178 | return ret; | 2203 | return ret; |
2179 | } | 2204 | } |
2180 | 2205 | ||
@@ -2183,12 +2208,14 @@ static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t volta | |||
2183 | struct av7110* av7110 = fe->dvb->priv; | 2208 | struct av7110* av7110 = fe->dvb->priv; |
2184 | 2209 | ||
2185 | int ret = av7110_fe_lock_fix(av7110, 0); | 2210 | int ret = av7110_fe_lock_fix(av7110, 0); |
2186 | if (!ret) | 2211 | if (!ret) { |
2212 | av7110->saved_voltage = voltage; | ||
2187 | ret = av7110->fe_set_voltage(fe, voltage); | 2213 | ret = av7110->fe_set_voltage(fe, voltage); |
2214 | } | ||
2188 | return ret; | 2215 | return ret; |
2189 | } | 2216 | } |
2190 | 2217 | ||
2191 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) | 2218 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd) |
2192 | { | 2219 | { |
2193 | struct av7110* av7110 = fe->dvb->priv; | 2220 | struct av7110* av7110 = fe->dvb->priv; |
2194 | 2221 | ||
@@ -2198,6 +2225,23 @@ static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, un | |||
2198 | return ret; | 2225 | return ret; |
2199 | } | 2226 | } |
2200 | 2227 | ||
2228 | static void dvb_s_recover(struct av7110* av7110) | ||
2229 | { | ||
2230 | av7110_fe_init(av7110->fe); | ||
2231 | |||
2232 | av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage); | ||
2233 | if (av7110->saved_master_cmd.msg_len) { | ||
2234 | msleep(20); | ||
2235 | av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd); | ||
2236 | } | ||
2237 | msleep(20); | ||
2238 | av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd); | ||
2239 | msleep(20); | ||
2240 | av7110_fe_set_tone(av7110->fe, av7110->saved_tone); | ||
2241 | |||
2242 | av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params); | ||
2243 | } | ||
2244 | |||
2201 | static u8 read_pwm(struct av7110* av7110) | 2245 | static u8 read_pwm(struct av7110* av7110) |
2202 | { | 2246 | { |
2203 | u8 b = 0xff; | 2247 | u8 b = 0xff; |
@@ -2235,6 +2279,7 @@ static int frontend_init(struct av7110 *av7110) | |||
2235 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2279 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2236 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2280 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2237 | av7110->fe->ops->set_tone = av7110_set_tone; | 2281 | av7110->fe->ops->set_tone = av7110_set_tone; |
2282 | av7110->recover = dvb_s_recover; | ||
2238 | break; | 2283 | break; |
2239 | } | 2284 | } |
2240 | 2285 | ||
@@ -2244,15 +2289,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2244 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2289 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2245 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2290 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2246 | av7110->fe->ops->set_tone = av7110_set_tone; | 2291 | av7110->fe->ops->set_tone = av7110_set_tone; |
2292 | av7110->recover = dvb_s_recover; | ||
2247 | break; | 2293 | break; |
2248 | } | 2294 | } |
2249 | 2295 | ||
2250 | // Try the grundig 29504-451 | 2296 | // Try the grundig 29504-451 |
2251 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2297 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
2252 | if (av7110->fe) { | 2298 | if (av7110->fe) { |
2253 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2299 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2254 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2300 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2255 | av7110->fe->ops->set_tone = av7110_set_tone; | 2301 | av7110->fe->ops->set_tone = av7110_set_tone; |
2302 | av7110->recover = dvb_s_recover; | ||
2256 | break; | 2303 | break; |
2257 | } | 2304 | } |
2258 | 2305 | ||
@@ -2274,12 +2321,12 @@ static int frontend_init(struct av7110 *av7110) | |||
2274 | case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X | 2321 | case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X |
2275 | 2322 | ||
2276 | // ALPS TDLB7 | 2323 | // ALPS TDLB7 |
2277 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); | 2324 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); |
2278 | break; | 2325 | break; |
2279 | 2326 | ||
2280 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X | 2327 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X |
2281 | 2328 | ||
2282 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | 2329 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); |
2283 | break; | 2330 | break; |
2284 | 2331 | ||
2285 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ | 2332 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ |
@@ -2289,6 +2336,7 @@ static int frontend_init(struct av7110 *av7110) | |||
2289 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2336 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2290 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2337 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2291 | av7110->fe->ops->set_tone = av7110_set_tone; | 2338 | av7110->fe->ops->set_tone = av7110_set_tone; |
2339 | av7110->recover = dvb_s_recover; | ||
2292 | } | 2340 | } |
2293 | break; | 2341 | break; |
2294 | 2342 | ||
@@ -2314,8 +2362,11 @@ static int frontend_init(struct av7110 *av7110) | |||
2314 | case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ | 2362 | case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ |
2315 | /* ALPS BSBE1 */ | 2363 | /* ALPS BSBE1 */ |
2316 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); | 2364 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); |
2317 | if (av7110->fe) | 2365 | if (av7110->fe) { |
2318 | av7110->fe->ops->set_voltage = lnbp21_set_voltage; | 2366 | av7110->fe->ops->set_voltage = lnbp21_set_voltage; |
2367 | av7110->fe->ops->dishnetwork_send_legacy_command = NULL; | ||
2368 | av7110->recover = dvb_s_recover; | ||
2369 | } | ||
2319 | break; | 2370 | break; |
2320 | } | 2371 | } |
2321 | } | 2372 | } |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index cce00ef293e9..6ea30df2e823 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -98,7 +98,8 @@ struct av7110 { | |||
98 | int adac_type; /* audio DAC type */ | 98 | int adac_type; /* audio DAC type */ |
99 | #define DVB_ADAC_TI 0 | 99 | #define DVB_ADAC_TI 0 |
100 | #define DVB_ADAC_CRYSTAL 1 | 100 | #define DVB_ADAC_CRYSTAL 1 |
101 | #define DVB_ADAC_MSP 2 | 101 | #define DVB_ADAC_MSP34x0 2 |
102 | #define DVB_ADAC_MSP34x5 3 | ||
102 | #define DVB_ADAC_NONE -1 | 103 | #define DVB_ADAC_NONE -1 |
103 | 104 | ||
104 | 105 | ||
@@ -228,6 +229,9 @@ struct av7110 { | |||
228 | struct dvb_video_events video_events; | 229 | struct dvb_video_events video_events; |
229 | video_size_t video_size; | 230 | video_size_t video_size; |
230 | 231 | ||
232 | u16 wssMode; | ||
233 | u16 wssData; | ||
234 | |||
231 | u32 ir_config; | 235 | u32 ir_config; |
232 | u32 ir_command; | 236 | u32 ir_command; |
233 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); | 237 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); |
@@ -245,6 +249,15 @@ struct av7110 { | |||
245 | 249 | ||
246 | struct dvb_frontend* fe; | 250 | struct dvb_frontend* fe; |
247 | fe_status_t fe_status; | 251 | fe_status_t fe_status; |
252 | |||
253 | /* crash recovery */ | ||
254 | void (*recover)(struct av7110* av7110); | ||
255 | struct dvb_frontend_parameters saved_fe_params; | ||
256 | fe_sec_voltage_t saved_voltage; | ||
257 | fe_sec_tone_mode_t saved_tone; | ||
258 | struct dvb_diseqc_master_cmd saved_master_cmd; | ||
259 | fe_sec_mini_cmd_t saved_minicmd; | ||
260 | |||
248 | int (*fe_init)(struct dvb_frontend* fe); | 261 | int (*fe_init)(struct dvb_frontend* fe); |
249 | int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); | 262 | int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); |
250 | int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); | 263 | int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); |
@@ -252,7 +265,7 @@ struct av7110 { | |||
252 | int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); | 265 | int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); |
253 | int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); | 266 | int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); |
254 | int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | 267 | int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); |
255 | int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); | 268 | int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); |
256 | int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 269 | int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
257 | }; | 270 | }; |
258 | 271 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 0696a5a4f855..400facec7407 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -309,7 +309,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) | |||
309 | i2c_writereg(av7110, 0x20, 0x04, volright); | 309 | i2c_writereg(av7110, 0x20, 0x04, volright); |
310 | return 0; | 310 | return 0; |
311 | 311 | ||
312 | case DVB_ADAC_MSP: | 312 | case DVB_ADAC_MSP34x0: |
313 | vol = (volleft > volright) ? volleft : volright; | 313 | vol = (volleft > volright) ? volleft : volright; |
314 | val = (vol * 0x73 / 255) << 8; | 314 | val = (vol * 0x73 / 255) << 8; |
315 | if (vol > 0) | 315 | if (vol > 0) |
@@ -1256,7 +1256,9 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1256 | break; | 1256 | break; |
1257 | 1257 | ||
1258 | case AUDIO_SET_BYPASS_MODE: | 1258 | case AUDIO_SET_BYPASS_MODE: |
1259 | ret = -EINVAL; | 1259 | if (FW_VERSION(av7110->arm_app) < 0x2621) |
1260 | ret = -EINVAL; | ||
1261 | av7110->audiostate.bypass_mode = (int)arg; | ||
1260 | break; | 1262 | break; |
1261 | 1263 | ||
1262 | case AUDIO_CHANNEL_SELECT: | 1264 | case AUDIO_CHANNEL_SELECT: |
@@ -1295,7 +1297,11 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1295 | break; | 1297 | break; |
1296 | 1298 | ||
1297 | case AUDIO_GET_CAPABILITIES: | 1299 | case AUDIO_GET_CAPABILITIES: |
1298 | *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | 1300 | if (FW_VERSION(av7110->arm_app) < 0x2621) |
1301 | *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | ||
1302 | else | ||
1303 | *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | | ||
1304 | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | ||
1299 | break; | 1305 | break; |
1300 | 1306 | ||
1301 | case AUDIO_CLEAR_BUFFER: | 1307 | case AUDIO_CLEAR_BUFFER: |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 87106e8bf35b..cb377452b57d 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -230,6 +230,8 @@ int av7110_bootarm(struct av7110 *av7110) | |||
230 | 230 | ||
231 | dprintk(4, "%p\n", av7110); | 231 | dprintk(4, "%p\n", av7110); |
232 | 232 | ||
233 | av7110->arm_ready = 0; | ||
234 | |||
233 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); | 235 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); |
234 | 236 | ||
235 | /* Disable DEBI and GPIO irq */ | 237 | /* Disable DEBI and GPIO irq */ |
@@ -361,6 +363,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | |||
361 | break; | 363 | break; |
362 | if (err) { | 364 | if (err) { |
363 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); | 365 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); |
366 | av7110->arm_errors++; | ||
364 | return -ETIMEDOUT; | 367 | return -ETIMEDOUT; |
365 | } | 368 | } |
366 | msleep(1); | 369 | msleep(1); |
@@ -1206,9 +1209,9 @@ int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap) | |||
1206 | switch (cap->cmd) { | 1209 | switch (cap->cmd) { |
1207 | case OSD_CAP_MEMSIZE: | 1210 | case OSD_CAP_MEMSIZE: |
1208 | if (FW_4M_SDRAM(av7110->arm_app)) | 1211 | if (FW_4M_SDRAM(av7110->arm_app)) |
1209 | cap->val = 1000000; | 1212 | cap->val = 1000000; |
1210 | else | 1213 | else |
1211 | cap->val = 92000; | 1214 | cap->val = 92000; |
1212 | return 0; | 1215 | return 0; |
1213 | default: | 1216 | default: |
1214 | return -EINVAL; | 1217 | return -EINVAL; |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index 2a5e87ba1052..84b83299b8be 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h | |||
@@ -167,7 +167,8 @@ enum av7110_encoder_command { | |||
167 | LoadVidCode, | 167 | LoadVidCode, |
168 | SetMonitorType, | 168 | SetMonitorType, |
169 | SetPanScanType, | 169 | SetPanScanType, |
170 | SetFreezeMode | 170 | SetFreezeMode, |
171 | SetWSSConfig | ||
171 | }; | 172 | }; |
172 | 173 | ||
173 | enum av7110_rec_play_state { | 174 | enum av7110_rec_play_state { |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index f5e59fc924af..9138132ad25f 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -17,6 +17,8 @@ static int av_cnt; | |||
17 | static struct av7110 *av_list[4]; | 17 | static struct av7110 *av_list[4]; |
18 | static struct input_dev *input_dev; | 18 | static struct input_dev *input_dev; |
19 | 19 | ||
20 | static u8 delay_timer_finished; | ||
21 | |||
20 | static u16 key_map [256] = { | 22 | static u16 key_map [256] = { |
21 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, | 23 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, |
22 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, | 24 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, |
@@ -112,13 +114,16 @@ static void av7110_emit_key(unsigned long parm) | |||
112 | if (timer_pending(&keyup_timer)) { | 114 | if (timer_pending(&keyup_timer)) { |
113 | del_timer(&keyup_timer); | 115 | del_timer(&keyup_timer); |
114 | if (keyup_timer.data != keycode || new_toggle != old_toggle) { | 116 | if (keyup_timer.data != keycode || new_toggle != old_toggle) { |
117 | delay_timer_finished = 0; | ||
115 | input_event(input_dev, EV_KEY, keyup_timer.data, !!0); | 118 | input_event(input_dev, EV_KEY, keyup_timer.data, !!0); |
116 | input_event(input_dev, EV_KEY, keycode, !0); | 119 | input_event(input_dev, EV_KEY, keycode, !0); |
117 | } else | 120 | } else |
118 | input_event(input_dev, EV_KEY, keycode, 2); | 121 | if (delay_timer_finished) |
119 | 122 | input_event(input_dev, EV_KEY, keycode, 2); | |
120 | } else | 123 | } else { |
124 | delay_timer_finished = 0; | ||
121 | input_event(input_dev, EV_KEY, keycode, !0); | 125 | input_event(input_dev, EV_KEY, keycode, !0); |
126 | } | ||
122 | 127 | ||
123 | keyup_timer.expires = jiffies + UP_TIMEOUT; | 128 | keyup_timer.expires = jiffies + UP_TIMEOUT; |
124 | keyup_timer.data = keycode; | 129 | keyup_timer.data = keycode; |
@@ -145,7 +150,8 @@ static void input_register_keys(void) | |||
145 | 150 | ||
146 | static void input_repeat_key(unsigned long data) | 151 | static void input_repeat_key(unsigned long data) |
147 | { | 152 | { |
148 | /* dummy routine to disable autorepeat in the input driver */ | 153 | /* called by the input driver after rep[REP_DELAY] ms */ |
154 | delay_timer_finished = 1; | ||
149 | } | 155 | } |
150 | 156 | ||
151 | 157 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index b5aea4129fa7..94cf38c7e8a8 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -490,6 +490,58 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
490 | dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); | 490 | dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); |
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | case VIDIOC_G_SLICED_VBI_CAP: | ||
494 | { | ||
495 | struct v4l2_sliced_vbi_cap *cap = arg; | ||
496 | dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); | ||
497 | memset(cap, 0, sizeof *cap); | ||
498 | if (FW_VERSION(av7110->arm_app) >= 0x2623) { | ||
499 | cap->service_set = V4L2_SLICED_WSS_625; | ||
500 | cap->service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
501 | } | ||
502 | break; | ||
503 | } | ||
504 | case VIDIOC_G_FMT: | ||
505 | { | ||
506 | struct v4l2_format *f = arg; | ||
507 | dprintk(2, "VIDIOC_G_FMT:\n"); | ||
508 | if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || | ||
509 | FW_VERSION(av7110->arm_app) < 0x2623) | ||
510 | return -EAGAIN; /* handled by core driver */ | ||
511 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
512 | if (av7110->wssMode) { | ||
513 | f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; | ||
514 | f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
515 | f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); | ||
516 | } | ||
517 | break; | ||
518 | } | ||
519 | case VIDIOC_S_FMT: | ||
520 | { | ||
521 | struct v4l2_format *f = arg; | ||
522 | dprintk(2, "VIDIOC_S_FMT\n"); | ||
523 | if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || | ||
524 | FW_VERSION(av7110->arm_app) < 0x2623) | ||
525 | return -EAGAIN; /* handled by core driver */ | ||
526 | if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && | ||
527 | f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { | ||
528 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
529 | /* WSS controlled by firmware */ | ||
530 | av7110->wssMode = 0; | ||
531 | av7110->wssData = 0; | ||
532 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, | ||
533 | SetWSSConfig, 1, 0); | ||
534 | } else { | ||
535 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
536 | f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; | ||
537 | f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
538 | f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); | ||
539 | /* WSS controlled by userspace */ | ||
540 | av7110->wssMode = 1; | ||
541 | av7110->wssData = 0; | ||
542 | } | ||
543 | break; | ||
544 | } | ||
493 | default: | 545 | default: |
494 | printk("no such ioctl\n"); | 546 | printk("no such ioctl\n"); |
495 | return -ENOIOCTLCMD; | 547 | return -ENOIOCTLCMD; |
@@ -497,6 +549,46 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
497 | return 0; | 549 | return 0; |
498 | } | 550 | } |
499 | 551 | ||
552 | static int av7110_vbi_reset(struct inode *inode, struct file *file) | ||
553 | { | ||
554 | struct saa7146_fh *fh = file->private_data; | ||
555 | struct saa7146_dev *dev = fh->dev; | ||
556 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
557 | |||
558 | dprintk(2, "%s\n", __FUNCTION__); | ||
559 | av7110->wssMode = 0; | ||
560 | av7110->wssData = 0; | ||
561 | if (FW_VERSION(av7110->arm_app) < 0x2623) | ||
562 | return 0; | ||
563 | else | ||
564 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); | ||
565 | } | ||
566 | |||
567 | static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) | ||
568 | { | ||
569 | struct saa7146_fh *fh = file->private_data; | ||
570 | struct saa7146_dev *dev = fh->dev; | ||
571 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
572 | struct v4l2_sliced_vbi_data d; | ||
573 | int rc; | ||
574 | |||
575 | dprintk(2, "%s\n", __FUNCTION__); | ||
576 | if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d) | ||
577 | return -EINVAL; | ||
578 | if (copy_from_user(&d, data, count)) | ||
579 | return -EFAULT; | ||
580 | if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) | ||
581 | return -EINVAL; | ||
582 | if (d.id) { | ||
583 | av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; | ||
584 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, | ||
585 | 2, 1, av7110->wssData); | ||
586 | } else { | ||
587 | av7110->wssData = 0; | ||
588 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); | ||
589 | } | ||
590 | return (rc < 0) ? rc : count; | ||
591 | } | ||
500 | 592 | ||
501 | /**************************************************************************** | 593 | /**************************************************************************** |
502 | * INITIALIZATION | 594 | * INITIALIZATION |
@@ -512,6 +604,9 @@ static struct saa7146_extension_ioctls ioctls[] = { | |||
512 | { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, | 604 | { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, |
513 | { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, | 605 | { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, |
514 | { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, | 606 | { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, |
607 | { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE }, | ||
608 | { VIDIOC_G_FMT, SAA7146_BEFORE }, | ||
609 | { VIDIOC_S_FMT, SAA7146_BEFORE }, | ||
515 | { 0, 0 } | 610 | { 0, 0 } |
516 | }; | 611 | }; |
517 | 612 | ||
@@ -587,7 +682,7 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
587 | 682 | ||
588 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", | 683 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", |
589 | av7110->dvb_adapter.num); | 684 | av7110->dvb_adapter.num); |
590 | av7110->adac_type = DVB_ADAC_MSP; | 685 | av7110->adac_type = DVB_ADAC_MSP34x0; |
591 | msleep(100); // the probing above resets the msp... | 686 | msleep(100); // the probing above resets the msp... |
592 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); | 687 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); |
593 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); | 688 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); |
@@ -692,12 +787,11 @@ int av7110_init_v4l(struct av7110 *av7110) | |||
692 | saa7146_vv_release(dev); | 787 | saa7146_vv_release(dev); |
693 | return -ENODEV; | 788 | return -ENODEV; |
694 | } | 789 | } |
695 | if (av7110->analog_tuner_flags) { | 790 | if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { |
696 | if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { | 791 | ERR(("cannot register vbi v4l2 device. skipping.\n")); |
697 | ERR(("cannot register vbi v4l2 device. skipping.\n")); | 792 | } else { |
698 | } else { | 793 | if (av7110->analog_tuner_flags) |
699 | av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; | 794 | av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; |
700 | } | ||
701 | } | 795 | } |
702 | return 0; | 796 | return 0; |
703 | } | 797 | } |
@@ -778,7 +872,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | |||
778 | static struct saa7146_ext_vv av7110_vv_data_st = { | 872 | static struct saa7146_ext_vv av7110_vv_data_st = { |
779 | .inputs = 1, | 873 | .inputs = 1, |
780 | .audios = 1, | 874 | .audios = 1, |
781 | .capabilities = 0, | 875 | .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT, |
782 | .flags = 0, | 876 | .flags = 0, |
783 | 877 | ||
784 | .stds = &standard[0], | 878 | .stds = &standard[0], |
@@ -787,12 +881,16 @@ static struct saa7146_ext_vv av7110_vv_data_st = { | |||
787 | 881 | ||
788 | .ioctls = &ioctls[0], | 882 | .ioctls = &ioctls[0], |
789 | .ioctl = av7110_ioctl, | 883 | .ioctl = av7110_ioctl, |
884 | |||
885 | .vbi_fops.open = av7110_vbi_reset, | ||
886 | .vbi_fops.release = av7110_vbi_reset, | ||
887 | .vbi_fops.write = av7110_vbi_write, | ||
790 | }; | 888 | }; |
791 | 889 | ||
792 | static struct saa7146_ext_vv av7110_vv_data_c = { | 890 | static struct saa7146_ext_vv av7110_vv_data_c = { |
793 | .inputs = 1, | 891 | .inputs = 1, |
794 | .audios = 1, | 892 | .audios = 1, |
795 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, | 893 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT, |
796 | .flags = SAA7146_USE_PORT_B_FOR_VBI, | 894 | .flags = SAA7146_USE_PORT_B_FOR_VBI, |
797 | 895 | ||
798 | .stds = &standard[0], | 896 | .stds = &standard[0], |
@@ -801,5 +899,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = { | |||
801 | 899 | ||
802 | .ioctls = &ioctls[0], | 900 | .ioctls = &ioctls[0], |
803 | .ioctl = av7110_ioctl, | 901 | .ioctl = av7110_ioctl, |
902 | |||
903 | .vbi_fops.open = av7110_vbi_reset, | ||
904 | .vbi_fops.release = av7110_vbi_reset, | ||
905 | .vbi_fops.write = av7110_vbi_write, | ||
804 | }; | 906 | }; |
805 | 907 | ||
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 9f51bae7194c..f9d00452e639 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -127,7 +127,7 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad | |||
127 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | 127 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); |
128 | udelay(1); | 128 | udelay(1); |
129 | 129 | ||
130 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0); | 130 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); |
131 | 131 | ||
132 | if (result == -ETIMEDOUT) | 132 | if (result == -ETIMEDOUT) |
133 | budget_av->slot_status = 0; | 133 | budget_av->slot_status = 0; |
@@ -145,7 +145,7 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a | |||
145 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | 145 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); |
146 | udelay(1); | 146 | udelay(1); |
147 | 147 | ||
148 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0); | 148 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); |
149 | 149 | ||
150 | if (result == -ETIMEDOUT) | 150 | if (result == -ETIMEDOUT) |
151 | budget_av->slot_status = 0; | 151 | budget_av->slot_status = 0; |
@@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
192 | { | 192 | { |
193 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 193 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
194 | struct saa7146_dev *saa = budget_av->budget.dev; | 194 | struct saa7146_dev *saa = budget_av->budget.dev; |
195 | int timeout = 500; // 5 seconds (4.4.6 Ready) | 195 | int timeout = 50; // 5 seconds (4.4.6 Ready) |
196 | 196 | ||
197 | if (slot != 0) | 197 | if (slot != 0) |
198 | return -EINVAL; | 198 | return -EINVAL; |
@@ -256,19 +256,37 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open | |||
256 | { | 256 | { |
257 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 257 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
258 | struct saa7146_dev *saa = budget_av->budget.dev; | 258 | struct saa7146_dev *saa = budget_av->budget.dev; |
259 | int cam_present = 0; | ||
259 | 260 | ||
260 | if (slot != 0) | 261 | if (slot != 0) |
261 | return -EINVAL; | 262 | return -EINVAL; |
262 | 263 | ||
263 | if (!budget_av->slot_status) { | 264 | if (!budget_av->slot_status) |
265 | { | ||
266 | // first of all test the card detect line | ||
264 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 267 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
265 | udelay(1); | 268 | udelay(1); |
266 | if (saa7146_read(saa, PSR) & MASK_06) | 269 | if (saa7146_read(saa, PSR) & MASK_06) |
267 | { | 270 | { |
271 | cam_present = 1; | ||
272 | } | ||
273 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
274 | |||
275 | // that is unreliable however, so try and read from IO memory | ||
276 | if (!cam_present) | ||
277 | { | ||
278 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
279 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) | ||
280 | { | ||
281 | cam_present = 1; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | // did we find something? | ||
286 | if (cam_present) { | ||
268 | printk(KERN_INFO "budget-av: cam inserted\n"); | 287 | printk(KERN_INFO "budget-av: cam inserted\n"); |
269 | budget_av->slot_status = 1; | 288 | budget_av->slot_status = 1; |
270 | } | 289 | } |
271 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
272 | } else if (!open) { | 290 | } else if (!open) { |
273 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 291 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); |
274 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) | 292 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) |
@@ -484,6 +502,140 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | |||
484 | return 0; | 502 | return 0; |
485 | } | 503 | } |
486 | 504 | ||
505 | #define MIN2(a,b) ((a) < (b) ? (a) : (b)) | ||
506 | #define MIN3(a,b,c) MIN2(MIN2(a,b),c) | ||
507 | |||
508 | static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | ||
509 | struct i2c_adapter *i2c, | ||
510 | struct dvb_frontend_parameters *params) | ||
511 | { | ||
512 | u8 reg0 [2] = { 0x00, 0x00 }; | ||
513 | u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; | ||
514 | u8 reg2 [3] = { 0x02, 0x00, 0x00 }; | ||
515 | int _fband; | ||
516 | int first_ZF; | ||
517 | int R, A, N, P, M; | ||
518 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; | ||
519 | int freq = params->frequency; | ||
520 | |||
521 | first_ZF = (freq) / 1000; | ||
522 | |||
523 | if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) < | ||
524 | abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890)))) | ||
525 | _fband = 2; | ||
526 | else | ||
527 | _fband = 3; | ||
528 | |||
529 | if (_fband == 2) { | ||
530 | if (((first_ZF >= 950) && (first_ZF < 1350)) || | ||
531 | ((first_ZF >= 1430) && (first_ZF < 1950))) | ||
532 | reg0[1] = 0x07; | ||
533 | else if (((first_ZF >= 1350) && (first_ZF < 1430)) || | ||
534 | ((first_ZF >= 1950) && (first_ZF < 2150))) | ||
535 | reg0[1] = 0x0B; | ||
536 | } | ||
537 | |||
538 | if(_fband == 3) { | ||
539 | if (((first_ZF >= 950) && (first_ZF < 1350)) || | ||
540 | ((first_ZF >= 1455) && (first_ZF < 1950))) | ||
541 | reg0[1] = 0x07; | ||
542 | else if (((first_ZF >= 1350) && (first_ZF < 1420)) || | ||
543 | ((first_ZF >= 1950) && (first_ZF < 2150))) | ||
544 | reg0[1] = 0x0B; | ||
545 | else if ((first_ZF >= 1420) && (first_ZF < 1455)) | ||
546 | reg0[1] = 0x0F; | ||
547 | } | ||
548 | |||
549 | if (first_ZF > 1525) | ||
550 | reg1[1] |= 0x80; | ||
551 | else | ||
552 | reg1[1] &= 0x7F; | ||
553 | |||
554 | if (_fband == 2) { | ||
555 | if (first_ZF > 1430) { /* 1430MHZ */ | ||
556 | reg1[1] &= 0xCF; /* N2 */ | ||
557 | reg2[1] &= 0xCF; /* R2 */ | ||
558 | reg2[1] |= 0x10; | ||
559 | } else { | ||
560 | reg1[1] &= 0xCF; /* N2 */ | ||
561 | reg1[1] |= 0x20; | ||
562 | reg2[1] &= 0xCF; /* R2 */ | ||
563 | reg2[1] |= 0x10; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | if (_fband == 3) { | ||
568 | if ((first_ZF >= 1455) && | ||
569 | (first_ZF < 1630)) { | ||
570 | reg1[1] &= 0xCF; /* N2 */ | ||
571 | reg1[1] |= 0x20; | ||
572 | reg2[1] &= 0xCF; /* R2 */ | ||
573 | } else { | ||
574 | if (first_ZF < 1455) { | ||
575 | reg1[1] &= 0xCF; /* N2 */ | ||
576 | reg1[1] |= 0x20; | ||
577 | reg2[1] &= 0xCF; /* R2 */ | ||
578 | reg2[1] |= 0x10; | ||
579 | } else { | ||
580 | if (first_ZF >= 1630) { | ||
581 | reg1[1] &= 0xCF; /* N2 */ | ||
582 | reg2[1] &= 0xCF; /* R2 */ | ||
583 | reg2[1] |= 0x10; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | |||
589 | /* set ports, enable P0 for symbol rates > 4Ms/s */ | ||
590 | if (params->u.qpsk.symbol_rate >= 4000000) | ||
591 | reg1[1] |= 0x0c; | ||
592 | else | ||
593 | reg1[1] |= 0x04; | ||
594 | |||
595 | reg2[1] |= 0x0c; | ||
596 | |||
597 | R = 64; | ||
598 | A = 64; | ||
599 | P = 64; //32 | ||
600 | |||
601 | M = (freq * R) / 4; /* in Mhz */ | ||
602 | N = (M - A * 1000) / (P * 1000); | ||
603 | |||
604 | reg1[1] |= (N >> 9) & 0x03; | ||
605 | reg1[2] = (N >> 1) & 0xff; | ||
606 | reg1[3] = (N << 7) & 0x80; | ||
607 | |||
608 | reg2[1] |= (R >> 8) & 0x03; | ||
609 | reg2[2] = R & 0xFF; /* R */ | ||
610 | |||
611 | reg1[3] |= A & 0x7f; /* A */ | ||
612 | |||
613 | if (P == 64) | ||
614 | reg1[1] |= 0x40; /* Prescaler 64/65 */ | ||
615 | |||
616 | reg0[1] |= 0x03; | ||
617 | |||
618 | /* already enabled - do not reenable i2c repeater or TX fails */ | ||
619 | msg.buf = reg0; | ||
620 | msg.len = sizeof(reg0); | ||
621 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
622 | return -EIO; | ||
623 | |||
624 | stv0299_enable_plli2c(fe); | ||
625 | msg.buf = reg1; | ||
626 | msg.len = sizeof(reg1); | ||
627 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
628 | return -EIO; | ||
629 | |||
630 | stv0299_enable_plli2c(fe); | ||
631 | msg.buf = reg2; | ||
632 | msg.len = sizeof(reg2); | ||
633 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
634 | return -EIO; | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
487 | static u8 typhoon_cinergy1200s_inittab[] = { | 639 | static u8 typhoon_cinergy1200s_inittab[] = { |
488 | 0x01, 0x15, | 640 | 0x01, 0x15, |
489 | 0x02, 0x30, | 641 | 0x02, 0x30, |
@@ -553,6 +705,18 @@ static struct stv0299_config cinergy_1200s_config = { | |||
553 | .pll_set = philips_su1278_ty_ci_pll_set, | 705 | .pll_set = philips_su1278_ty_ci_pll_set, |
554 | }; | 706 | }; |
555 | 707 | ||
708 | static struct stv0299_config cinergy_1200s_1894_0010_config = { | ||
709 | .demod_address = 0x68, | ||
710 | .inittab = typhoon_cinergy1200s_inittab, | ||
711 | .mclk = 88000000UL, | ||
712 | .invert = 1, | ||
713 | .skip_reinit = 0, | ||
714 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
715 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
716 | .min_delay_ms = 100, | ||
717 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | ||
718 | .pll_set = philips_su1278sh2_tua6100_pll_set, | ||
719 | }; | ||
556 | 720 | ||
557 | static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 721 | static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
558 | { | 722 | { |
@@ -749,6 +913,15 @@ static void frontend_init(struct budget_av *budget_av) | |||
749 | switch (saa->pci->subsystem_device) { | 913 | switch (saa->pci->subsystem_device) { |
750 | 914 | ||
751 | case SUBID_DVBS_KNC1: | 915 | case SUBID_DVBS_KNC1: |
916 | if (saa->pci->subsystem_vendor == 0x1894) { | ||
917 | fe = stv0299_attach(&cinergy_1200s_1894_0010_config, | ||
918 | &budget_av->budget.i2c_adap); | ||
919 | } else { | ||
920 | fe = stv0299_attach(&typhoon_config, | ||
921 | &budget_av->budget.i2c_adap); | ||
922 | } | ||
923 | break; | ||
924 | |||
752 | case SUBID_DVBS_KNC1_PLUS: | 925 | case SUBID_DVBS_KNC1_PLUS: |
753 | case SUBID_DVBS_TYPHOON: | 926 | case SUBID_DVBS_TYPHOON: |
754 | fe = stv0299_attach(&typhoon_config, | 927 | fe = stv0299_attach(&typhoon_config, |
@@ -1003,6 +1176,7 @@ MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); | |||
1003 | static struct pci_device_id pci_tbl[] = { | 1176 | static struct pci_device_id pci_tbl[] = { |
1004 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), | 1177 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), |
1005 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), | 1178 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), |
1179 | MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), | ||
1006 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), | 1180 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), |
1007 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1181 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
1008 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 1182 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 017fcbccb8cc..633e68c341c8 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -404,9 +404,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
404 | tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); | 404 | tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); |
405 | 405 | ||
406 | /* frontend power on */ | 406 | /* frontend power on */ |
407 | if (bi->type == BUDGET_FS_ACTIVY) | 407 | if (bi->type != BUDGET_FS_ACTIVY) |
408 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
409 | else | ||
410 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); | 408 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); |
411 | 409 | ||
412 | if (budget_register(budget) == 0) { | 410 | if (budget_register(budget) == 0) { |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index fafe6407b3d0..238c77b52f89 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -112,6 +112,7 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long | |||
112 | * Routines for the Fujitsu Siemens Activy budget card | 112 | * Routines for the Fujitsu Siemens Activy budget card |
113 | * 22 kHz tone and DiSEqC are handled by the frontend. | 113 | * 22 kHz tone and DiSEqC are handled by the frontend. |
114 | * Voltage must be set here. | 114 | * Voltage must be set here. |
115 | * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL | ||
115 | */ | 116 | */ |
116 | static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) | 117 | static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) |
117 | { | 118 | { |
@@ -121,11 +122,16 @@ static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) | |||
121 | 122 | ||
122 | switch (voltage) { | 123 | switch (voltage) { |
123 | case SEC_VOLTAGE_13: | 124 | case SEC_VOLTAGE_13: |
125 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
124 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); | 126 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); |
125 | break; | 127 | break; |
126 | case SEC_VOLTAGE_18: | 128 | case SEC_VOLTAGE_18: |
129 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
127 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); | 130 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); |
128 | break; | 131 | break; |
132 | case SEC_VOLTAGE_OFF: | ||
133 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); | ||
134 | break; | ||
129 | default: | 135 | default: |
130 | return -EINVAL; | 136 | return -EINVAL; |
131 | } | 137 | } |
@@ -206,7 +212,7 @@ static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | |||
206 | return 0; | 212 | return 0; |
207 | } | 213 | } |
208 | 214 | ||
209 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg) | 215 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg) |
210 | { | 216 | { |
211 | struct budget* budget = (struct budget*) fe->dvb->priv; | 217 | struct budget* budget = (struct budget*) fe->dvb->priv; |
212 | u8 buf; | 218 | u8 buf; |
@@ -580,6 +586,7 @@ static void frontend_init(struct budget *budget) | |||
580 | if (budget->dvb_frontend) { | 586 | if (budget->dvb_frontend) { |
581 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; | 587 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; |
582 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | 588 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; |
589 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | ||
583 | if (lnbp21_init(budget)) { | 590 | if (lnbp21_init(budget)) { |
584 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 591 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
585 | goto error_out; | 592 | goto error_out; |
@@ -624,7 +631,7 @@ static void frontend_init(struct budget *budget) | |||
624 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 631 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
625 | if (budget->dvb_frontend) { | 632 | if (budget->dvb_frontend) { |
626 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 633 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; |
627 | break; | 634 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; |
628 | } | 635 | } |
629 | break; | 636 | break; |
630 | 637 | ||
@@ -632,7 +639,7 @@ static void frontend_init(struct budget *budget) | |||
632 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); | 639 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); |
633 | if (budget->dvb_frontend) { | 640 | if (budget->dvb_frontend) { |
634 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 641 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; |
635 | break; | 642 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; |
636 | } | 643 | } |
637 | break; | 644 | break; |
638 | 645 | ||
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c index 18aa22b5478d..1f31e91195b0 100644 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c | |||
@@ -13,7 +13,7 @@ | |||
13 | Holger Waechtler Convergence | 13 | Holger Waechtler Convergence |
14 | 14 | ||
15 | Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> | 15 | Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> |
16 | Metzler Brothers Systementwicklung GbR | 16 | Metzler Brothers Systementwicklung GbR |
17 | 17 | ||
18 | This program is free software; you can redistribute it and/or modify | 18 | This program is free software; you can redistribute it and/or modify |
19 | it under the terms of the GNU General Public License as published by | 19 | it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index c6c1d41a2efb..914587d52b57 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig | |||
@@ -10,7 +10,7 @@ config DVB_TTUSB_BUDGET | |||
10 | Support for external USB adapters designed by Technotrend and | 10 | Support for external USB adapters designed by Technotrend and |
11 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. | 11 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. |
12 | 12 | ||
13 | These devices don't have a MPEG decoder built in, so you need | 13 | These devices don't have a MPEG decoder built in, so you need |
14 | an external software decoder to watch TV. | 14 | an external software decoder to watch TV. |
15 | 15 | ||
16 | Say Y if you own such a device and want to use it. | 16 | Say Y if you own such a device and want to use it. |
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index c334526af66f..83611012ef34 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig | |||
@@ -8,14 +8,15 @@ config DVB_TTUSB_DEC | |||
8 | produced by Hauppauge, shipped under the brand name 'DEC2000-t' | 8 | produced by Hauppauge, shipped under the brand name 'DEC2000-t' |
9 | and 'DEC3000-s'. | 9 | and 'DEC3000-s'. |
10 | 10 | ||
11 | Even if these devices have a MPEG decoder built in, they transmit | 11 | Even if these devices have a MPEG decoder built in, they transmit |
12 | only compressed MPEG data over the USB bus, so you need | 12 | only compressed MPEG data over the USB bus, so you need |
13 | an external software decoder to watch TV on your computer. | 13 | an external software decoder to watch TV on your computer. |
14 | 14 | ||
15 | This driver needs external firmware. Please use the commands | 15 | This driver needs external firmware. Please use the commands |
16 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", | 16 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", |
17 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", | 17 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", |
18 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", | 18 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", |
19 | download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 19 | download/extract them, and then copy them to /usr/lib/hotplug/firmware |
20 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
20 | 21 | ||
21 | Say Y if you own such a device and want to use it. | 22 | Say Y if you own such a device and want to use it. |
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 8abc21890129..d8966d1d25ee 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
@@ -369,7 +369,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, | |||
369 | 369 | ||
370 | static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) | 370 | static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) |
371 | { | 371 | { |
372 | struct ttusb_dec *dec = (struct ttusb_dec *)priv; | 372 | struct ttusb_dec *dec = priv; |
373 | 373 | ||
374 | dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, | 374 | dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, |
375 | &dec->audio_filter->feed->feed.ts, | 375 | &dec->audio_filter->feed->feed.ts, |
@@ -380,7 +380,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) | |||
380 | 380 | ||
381 | static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) | 381 | static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) |
382 | { | 382 | { |
383 | struct ttusb_dec *dec = (struct ttusb_dec *)priv; | 383 | struct ttusb_dec *dec = priv; |
384 | 384 | ||
385 | dec->video_filter->feed->cb.ts(data, 188, NULL, 0, | 385 | dec->video_filter->feed->cb.ts(data, 188, NULL, 0, |
386 | &dec->video_filter->feed->feed.ts, | 386 | &dec->video_filter->feed->feed.ts, |
@@ -965,8 +965,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
965 | 965 | ||
966 | case DMX_TS_PES_TELETEXT: | 966 | case DMX_TS_PES_TELETEXT: |
967 | dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; | 967 | dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; |
968 | dprintk(" pes_type: DMX_TS_PES_TELETEXT\n"); | 968 | dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n"); |
969 | break; | 969 | return -ENOSYS; |
970 | 970 | ||
971 | case DMX_TS_PES_PCR: | 971 | case DMX_TS_PES_PCR: |
972 | dprintk(" pes_type: DMX_TS_PES_PCR\n"); | 972 | dprintk(" pes_type: DMX_TS_PES_PCR\n"); |
@@ -975,8 +975,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
975 | break; | 975 | break; |
976 | 976 | ||
977 | case DMX_TS_PES_OTHER: | 977 | case DMX_TS_PES_OTHER: |
978 | dprintk(" pes_type: DMX_TS_PES_OTHER\n"); | 978 | dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n"); |
979 | break; | 979 | return -ENOSYS; |
980 | 980 | ||
981 | default: | 981 | default: |
982 | dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); | 982 | dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); |
@@ -1182,7 +1182,7 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) | |||
1182 | (unsigned long)dec); | 1182 | (unsigned long)dec); |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | static int ttusb_init_rc(struct ttusb_dec *dec) | 1185 | static int ttusb_init_rc( struct ttusb_dec *dec) |
1186 | { | 1186 | { |
1187 | struct input_dev *input_dev; | 1187 | struct input_dev *input_dev; |
1188 | u8 b[] = { 0x00, 0x01 }; | 1188 | u8 b[] = { 0x00, 0x01 }; |
@@ -1203,13 +1203,12 @@ static int ttusb_init_rc(struct ttusb_dec *dec) | |||
1203 | input_dev->keycode = rc_keys; | 1203 | input_dev->keycode = rc_keys; |
1204 | 1204 | ||
1205 | for (i = 0; i < ARRAY_SIZE(rc_keys); i++) | 1205 | for (i = 0; i < ARRAY_SIZE(rc_keys); i++) |
1206 | set_bit(rc_keys[i], input_dev->keybit); | 1206 | set_bit(rc_keys[i], input_dev->keybit); |
1207 | 1207 | ||
1208 | input_register_device(input_dev); | 1208 | input_register_device(input_dev); |
1209 | 1209 | ||
1210 | if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) | 1210 | if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) |
1211 | printk("%s: usb_submit_urb failed\n",__FUNCTION__); | 1211 | printk("%s: usb_submit_urb failed\n",__FUNCTION__); |
1212 | |||
1213 | /* enable irq pipe */ | 1212 | /* enable irq pipe */ |
1214 | ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); | 1213 | ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); |
1215 | 1214 | ||
@@ -1395,6 +1394,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) | |||
1395 | /* We can't trust the USB IDs that some firmwares | 1394 | /* We can't trust the USB IDs that some firmwares |
1396 | give the box */ | 1395 | give the box */ |
1397 | switch (model) { | 1396 | switch (model) { |
1397 | case 0x00070001: | ||
1398 | case 0x00070008: | 1398 | case 0x00070008: |
1399 | case 0x0007000c: | 1399 | case 0x0007000c: |
1400 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); | 1400 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); |
@@ -1588,7 +1588,7 @@ static int fe_send_command(struct dvb_frontend* fe, const u8 command, | |||
1588 | int param_length, const u8 params[], | 1588 | int param_length, const u8 params[], |
1589 | int *result_length, u8 cmd_result[]) | 1589 | int *result_length, u8 cmd_result[]) |
1590 | { | 1590 | { |
1591 | struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; | 1591 | struct ttusb_dec* dec = fe->dvb->priv; |
1592 | return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); | 1592 | return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); |
1593 | } | 1593 | } |
1594 | 1594 | ||
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 725af3af5b27..a5a46175fa09 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |||
@@ -42,8 +42,39 @@ struct ttusbdecfe_state { | |||
42 | 42 | ||
43 | static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) | 43 | static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) |
44 | { | 44 | { |
45 | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | | 45 | struct ttusbdecfe_state* state = fe->demodulator_priv; |
46 | FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; | 46 | u8 b[] = { 0x00, 0x00, 0x00, 0x00, |
47 | 0x00, 0x00, 0x00, 0x00 }; | ||
48 | u8 result[4]; | ||
49 | int len, ret; | ||
50 | |||
51 | *status=0; | ||
52 | |||
53 | ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result); | ||
54 | if(ret) | ||
55 | return ret; | ||
56 | |||
57 | if(len != 4) { | ||
58 | printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__); | ||
59 | return -EIO; | ||
60 | } | ||
61 | |||
62 | switch(result[3]) { | ||
63 | case 1: /* not tuned yet */ | ||
64 | case 2: /* no signal/no lock*/ | ||
65 | break; | ||
66 | case 3: /* signal found and locked*/ | ||
67 | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | | ||
68 | FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
69 | break; | ||
70 | case 4: | ||
71 | *status = FE_TIMEDOUT; | ||
72 | break; | ||
73 | default: | ||
74 | pr_info("%s: returned unknown value: %d\n", | ||
75 | __FUNCTION__, result[3]); | ||
76 | return -EIO; | ||
77 | } | ||
47 | 78 | ||
48 | return 0; | 79 | return 0; |
49 | } | 80 | } |
@@ -64,6 +95,16 @@ static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_fron | |||
64 | return 0; | 95 | return 0; |
65 | } | 96 | } |
66 | 97 | ||
98 | static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, | ||
99 | struct dvb_frontend_tune_settings* fesettings) | ||
100 | { | ||
101 | fesettings->min_delay_ms = 1500; | ||
102 | /* Drift compensation makes no sense for DVB-T */ | ||
103 | fesettings->step_size = 0; | ||
104 | fesettings->max_drift = 0; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
67 | static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 108 | static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
68 | { | 109 | { |
69 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | 110 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; |
@@ -212,6 +253,8 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { | |||
212 | 253 | ||
213 | .set_frontend = ttusbdecfe_dvbt_set_frontend, | 254 | .set_frontend = ttusbdecfe_dvbt_set_frontend, |
214 | 255 | ||
256 | .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, | ||
257 | |||
215 | .read_status = ttusbdecfe_read_status, | 258 | .read_status = ttusbdecfe_read_status, |
216 | }; | 259 | }; |
217 | 260 | ||
@@ -223,11 +266,11 @@ static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { | |||
223 | .frequency_min = 950000, | 266 | .frequency_min = 950000, |
224 | .frequency_max = 2150000, | 267 | .frequency_max = 2150000, |
225 | .frequency_stepsize = 125, | 268 | .frequency_stepsize = 125, |
269 | .symbol_rate_min = 1000000, /* guessed */ | ||
270 | .symbol_rate_max = 45000000, /* guessed */ | ||
226 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 271 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
227 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 272 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
228 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | 273 | FE_CAN_QPSK |
229 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | ||
230 | FE_CAN_HIERARCHY_AUTO, | ||
231 | }, | 274 | }, |
232 | 275 | ||
233 | .release = ttusbdecfe_release, | 276 | .release = ttusbdecfe_release, |
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index c2ebe8754a95..dc292da2605f 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c | |||
@@ -220,6 +220,7 @@ static struct file_operations pcm20_fops = { | |||
220 | .open = video_exclusive_open, | 220 | .open = video_exclusive_open, |
221 | .release = video_exclusive_release, | 221 | .release = video_exclusive_release, |
222 | .ioctl = pcm20_ioctl, | 222 | .ioctl = pcm20_ioctl, |
223 | .compat_ioctl = v4l_compat_ioctl32, | ||
223 | .llseek = no_llseek, | 224 | .llseek = no_llseek, |
224 | }; | 225 | }; |
225 | 226 | ||
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 877c770558e9..914deab4e044 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
@@ -299,6 +299,7 @@ static struct file_operations rtrack_fops = { | |||
299 | .open = video_exclusive_open, | 299 | .open = video_exclusive_open, |
300 | .release = video_exclusive_release, | 300 | .release = video_exclusive_release, |
301 | .ioctl = rt_ioctl, | 301 | .ioctl = rt_ioctl, |
302 | .compat_ioctl = v4l_compat_ioctl32, | ||
302 | .llseek = no_llseek, | 303 | .llseek = no_llseek, |
303 | }; | 304 | }; |
304 | 305 | ||
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 5319a9c9a979..523be820f9c6 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
@@ -256,6 +256,7 @@ static struct file_operations aztech_fops = { | |||
256 | .open = video_exclusive_open, | 256 | .open = video_exclusive_open, |
257 | .release = video_exclusive_release, | 257 | .release = video_exclusive_release, |
258 | .ioctl = az_ioctl, | 258 | .ioctl = az_ioctl, |
259 | .compat_ioctl = v4l_compat_ioctl32, | ||
259 | .llseek = no_llseek, | 260 | .llseek = no_llseek, |
260 | }; | 261 | }; |
261 | 262 | ||
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 9b0406318f2d..f1b5ac81e9d2 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
@@ -490,6 +490,7 @@ static struct file_operations cadet_fops = { | |||
490 | .release = cadet_release, | 490 | .release = cadet_release, |
491 | .read = cadet_read, | 491 | .read = cadet_read, |
492 | .ioctl = cadet_ioctl, | 492 | .ioctl = cadet_ioctl, |
493 | .compat_ioctl = v4l_compat_ioctl32, | ||
493 | .llseek = no_llseek, | 494 | .llseek = no_llseek, |
494 | }; | 495 | }; |
495 | 496 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 630cc786d0a4..42c8fce04aa2 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -301,6 +301,7 @@ static struct file_operations gemtek_pci_fops = { | |||
301 | .open = video_exclusive_open, | 301 | .open = video_exclusive_open, |
302 | .release = video_exclusive_release, | 302 | .release = video_exclusive_release, |
303 | .ioctl = gemtek_pci_ioctl, | 303 | .ioctl = gemtek_pci_ioctl, |
304 | .compat_ioctl = v4l_compat_ioctl32, | ||
304 | .llseek = no_llseek, | 305 | .llseek = no_llseek, |
305 | }; | 306 | }; |
306 | 307 | ||
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 6418f03b9ce4..47173be97b9f 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
@@ -233,6 +233,7 @@ static struct file_operations gemtek_fops = { | |||
233 | .open = video_exclusive_open, | 233 | .open = video_exclusive_open, |
234 | .release = video_exclusive_release, | 234 | .release = video_exclusive_release, |
235 | .ioctl = gemtek_ioctl, | 235 | .ioctl = gemtek_ioctl, |
236 | .compat_ioctl = v4l_compat_ioctl32, | ||
236 | .llseek = no_llseek, | 237 | .llseek = no_llseek, |
237 | }; | 238 | }; |
238 | 239 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index e5e2021a7312..c30effdf711f 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
@@ -72,6 +72,7 @@ static struct file_operations maestro_fops = { | |||
72 | .open = video_exclusive_open, | 72 | .open = video_exclusive_open, |
73 | .release = video_exclusive_release, | 73 | .release = video_exclusive_release, |
74 | .ioctl = radio_ioctl, | 74 | .ioctl = radio_ioctl, |
75 | .compat_ioctl = v4l_compat_ioctl32, | ||
75 | .llseek = no_llseek, | 76 | .llseek = no_llseek, |
76 | }; | 77 | }; |
77 | 78 | ||
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 02d39a50d5ed..30869308332a 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
@@ -80,6 +80,7 @@ static struct file_operations maxiradio_fops = { | |||
80 | .open = video_exclusive_open, | 80 | .open = video_exclusive_open, |
81 | .release = video_exclusive_release, | 81 | .release = video_exclusive_release, |
82 | .ioctl = radio_ioctl, | 82 | .ioctl = radio_ioctl, |
83 | .compat_ioctl = v4l_compat_ioctl32, | ||
83 | .llseek = no_llseek, | 84 | .llseek = no_llseek, |
84 | }; | 85 | }; |
85 | static struct video_device maxiradio_radio = | 86 | static struct video_device maxiradio_radio = |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index b2256d675b44..28a47c9e7a81 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
@@ -199,6 +199,7 @@ static struct file_operations rtrack2_fops = { | |||
199 | .open = video_exclusive_open, | 199 | .open = video_exclusive_open, |
200 | .release = video_exclusive_release, | 200 | .release = video_exclusive_release, |
201 | .ioctl = rt_ioctl, | 201 | .ioctl = rt_ioctl, |
202 | .compat_ioctl = v4l_compat_ioctl32, | ||
202 | .llseek = no_llseek, | 203 | .llseek = no_llseek, |
203 | }; | 204 | }; |
204 | 205 | ||
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 6f03ce4dd7b0..0229f792a059 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -225,6 +225,7 @@ static struct file_operations fmi_fops = { | |||
225 | .open = video_exclusive_open, | 225 | .open = video_exclusive_open, |
226 | .release = video_exclusive_release, | 226 | .release = video_exclusive_release, |
227 | .ioctl = fmi_ioctl, | 227 | .ioctl = fmi_ioctl, |
228 | .compat_ioctl = v4l_compat_ioctl32, | ||
228 | .llseek = no_llseek, | 229 | .llseek = no_llseek, |
229 | }; | 230 | }; |
230 | 231 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 71971e9bb342..26632cead09a 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -356,6 +356,7 @@ static struct file_operations fmr2_fops = { | |||
356 | .open = video_exclusive_open, | 356 | .open = video_exclusive_open, |
357 | .release = video_exclusive_release, | 357 | .release = video_exclusive_release, |
358 | .ioctl = fmr2_ioctl, | 358 | .ioctl = fmr2_ioctl, |
359 | .compat_ioctl = v4l_compat_ioctl32, | ||
359 | .llseek = no_llseek, | 360 | .llseek = no_llseek, |
360 | }; | 361 | }; |
361 | 362 | ||
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index b03573c6840e..fcfde2e4f195 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
@@ -276,6 +276,7 @@ static struct file_operations terratec_fops = { | |||
276 | .open = video_exclusive_open, | 276 | .open = video_exclusive_open, |
277 | .release = video_exclusive_release, | 277 | .release = video_exclusive_release, |
278 | .ioctl = tt_ioctl, | 278 | .ioctl = tt_ioctl, |
279 | .compat_ioctl = v4l_compat_ioctl32, | ||
279 | .llseek = no_llseek, | 280 | .llseek = no_llseek, |
280 | }; | 281 | }; |
281 | 282 | ||
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index b300bedf7c74..5a099a50d4d0 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
@@ -255,6 +255,7 @@ static struct file_operations trust_fops = { | |||
255 | .open = video_exclusive_open, | 255 | .open = video_exclusive_open, |
256 | .release = video_exclusive_release, | 256 | .release = video_exclusive_release, |
257 | .ioctl = tr_ioctl, | 257 | .ioctl = tr_ioctl, |
258 | .compat_ioctl = v4l_compat_ioctl32, | ||
258 | .llseek = no_llseek, | 259 | .llseek = no_llseek, |
259 | }; | 260 | }; |
260 | 261 | ||
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index f304f3c14763..8ac9a8ef9094 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
@@ -261,6 +261,7 @@ static struct file_operations typhoon_fops = { | |||
261 | .open = video_exclusive_open, | 261 | .open = video_exclusive_open, |
262 | .release = video_exclusive_release, | 262 | .release = video_exclusive_release, |
263 | .ioctl = typhoon_ioctl, | 263 | .ioctl = typhoon_ioctl, |
264 | .compat_ioctl = v4l_compat_ioctl32, | ||
264 | .llseek = no_llseek, | 265 | .llseek = no_llseek, |
265 | }; | 266 | }; |
266 | 267 | ||
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 4c6d6fb49034..d590e80c922e 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
@@ -313,6 +313,7 @@ static struct file_operations zoltrix_fops = | |||
313 | .open = video_exclusive_open, | 313 | .open = video_exclusive_open, |
314 | .release = video_exclusive_release, | 314 | .release = video_exclusive_release, |
315 | .ioctl = zol_ioctl, | 315 | .ioctl = zol_ioctl, |
316 | .compat_ioctl = v4l_compat_ioctl32, | ||
316 | .llseek = no_llseek, | 317 | .llseek = no_llseek, |
317 | }; | 318 | }; |
318 | 319 | ||
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index fc87efc5049c..2fe260fff85d 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -7,6 +7,15 @@ menu "Video For Linux" | |||
7 | 7 | ||
8 | comment "Video Adapters" | 8 | comment "Video Adapters" |
9 | 9 | ||
10 | config VIDEO_ADV_DEBUG | ||
11 | bool "Enable advanced debug functionality" | ||
12 | depends on VIDEO_DEV | ||
13 | default n | ||
14 | ---help--- | ||
15 | Say Y here to enable advanced debugging functionality on some | ||
16 | V4L devices. | ||
17 | In doubt, say N. | ||
18 | |||
10 | config VIDEO_BT848 | 19 | config VIDEO_BT848 |
11 | tristate "BT848 Video For Linux" | 20 | tristate "BT848 Video For Linux" |
12 | depends on VIDEO_DEV && PCI && I2C | 21 | depends on VIDEO_DEV && PCI && I2C |
@@ -342,6 +351,6 @@ config VIDEO_DECODER | |||
342 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | 351 | depends on VIDEO_DEV && I2C && EXPERIMENTAL |
343 | ---help--- | 352 | ---help--- |
344 | Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 | 353 | Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 |
345 | video decoders. | 354 | video decoders. |
346 | 355 | ||
347 | endmenu | 356 | endmenu |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 82060f9909d8..dd24896906fe 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -3,15 +3,19 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ | 5 | bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ |
6 | bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o | 6 | bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \ |
7 | bttv-input.o | ||
7 | zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o | 8 | zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o |
8 | zr36067-objs := zoran_procfs.o zoran_device.o \ | 9 | zr36067-objs := zoran_procfs.o zoran_device.o \ |
9 | zoran_driver.o zoran_card.o | 10 | zoran_driver.o zoran_card.o |
10 | tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o | 11 | tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o |
11 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o | 12 | |
13 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o | ||
14 | |||
15 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o | ||
12 | 16 | ||
13 | obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ | 17 | obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ |
14 | tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o | 18 | tda7432.o tda9875.o ir-kbd-i2c.o |
15 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o | 19 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o |
16 | 20 | ||
17 | obj-$(CONFIG_VIDEO_ZR36120) += zoran.o | 21 | obj-$(CONFIG_VIDEO_ZR36120) += zoran.o |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 881cdcb1875d..7d5a068353f2 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -749,6 +749,7 @@ static struct file_operations ar_fops = { | |||
749 | .release = video_exclusive_release, | 749 | .release = video_exclusive_release, |
750 | .read = ar_read, | 750 | .read = ar_read, |
751 | .ioctl = ar_ioctl, | 751 | .ioctl = ar_ioctl, |
752 | .compat_ioctl = v4l_compat_ioctl32, | ||
752 | .llseek = no_llseek, | 753 | .llseek = no_llseek, |
753 | }; | 754 | }; |
754 | 755 | ||
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 1c3ff5f38a6d..dda4aa6bef27 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c | |||
@@ -30,8 +30,9 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | |||
34 | #include <media/audiochip.h> | 33 | #include <media/audiochip.h> |
34 | #include <media/v4l2-common.h> | ||
35 | |||
35 | #include "bttv.h" | 36 | #include "bttv.h" |
36 | #include "bt832.h" | 37 | #include "bt832.h" |
37 | 38 | ||
@@ -42,9 +43,10 @@ static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1, | |||
42 | I2C_CLIENT_END }; | 43 | I2C_CLIENT_END }; |
43 | I2C_CLIENT_INSMOD; | 44 | I2C_CLIENT_INSMOD; |
44 | 45 | ||
45 | /* ---------------------------------------------------------------------- */ | 46 | int debug = 0; /* debug output */ |
47 | module_param(debug, int, 0644); | ||
46 | 48 | ||
47 | #define dprintk if (debug) printk | 49 | /* ---------------------------------------------------------------------- */ |
48 | 50 | ||
49 | static int bt832_detach(struct i2c_client *client); | 51 | static int bt832_detach(struct i2c_client *client); |
50 | 52 | ||
@@ -61,23 +63,26 @@ int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) | |||
61 | int i,rc; | 63 | int i,rc; |
62 | buf[0]=0x80; // start at register 0 with auto-increment | 64 | buf[0]=0x80; // start at register 0 with auto-increment |
63 | if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) | 65 | if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) |
64 | printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); | 66 | v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 1)\n",rc); |
65 | 67 | ||
66 | for(i=0;i<65;i++) | 68 | for(i=0;i<65;i++) |
67 | buf[i]=0; | 69 | buf[i]=0; |
68 | if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) | 70 | if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) |
69 | printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); | 71 | v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 65)\n",rc); |
70 | 72 | ||
71 | // Note: On READ the first byte is the current index | 73 | // Note: On READ the first byte is the current index |
72 | // (e.g. 0x80, what we just wrote) | 74 | // (e.g. 0x80, what we just wrote) |
73 | 75 | ||
74 | if(1) { | 76 | if(debug>1) { |
75 | int i; | 77 | int i; |
76 | printk("BT832 hexdump:\n"); | 78 | v4l_dbg(2,i2c_client_s,"hexdump:"); |
77 | for(i=1;i<65;i++) { | 79 | for(i=1;i<65;i++) { |
78 | if(i!=1) { | 80 | if(i!=1) { |
79 | if(((i-1)%8)==0) printk(" "); | 81 | if(((i-1)%8)==0) printk(" "); |
80 | if(((i-1)%16)==0) printk("\n"); | 82 | if(((i-1)%16)==0) { |
83 | printk("\n"); | ||
84 | v4l_dbg(2,i2c_client_s,"hexdump:"); | ||
85 | } | ||
81 | } | 86 | } |
82 | printk(" %02x",buf[i]); | 87 | printk(" %02x",buf[i]); |
83 | } | 88 | } |
@@ -96,56 +101,56 @@ int bt832_init(struct i2c_client *i2c_client_s) | |||
96 | bt832_hexdump(i2c_client_s,buf); | 101 | bt832_hexdump(i2c_client_s,buf); |
97 | 102 | ||
98 | if(buf[0x40] != 0x31) { | 103 | if(buf[0x40] != 0x31) { |
99 | printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); | 104 | v4l_err(i2c_client_s,"This i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); |
100 | kfree(buf); | 105 | kfree(buf); |
101 | return 0; | 106 | return 0; |
102 | } | 107 | } |
103 | 108 | ||
104 | printk("Write 0 tp VPSTATUS\n"); | 109 | v4l_err(i2c_client_s,"Write 0 tp VPSTATUS\n"); |
105 | buf[0]=BT832_VP_STATUS; // Reg.52 | 110 | buf[0]=BT832_VP_STATUS; // Reg.52 |
106 | buf[1]= 0x00; | 111 | buf[1]= 0x00; |
107 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 112 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
108 | printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); | 113 | v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc); |
109 | 114 | ||
110 | bt832_hexdump(i2c_client_s,buf); | 115 | bt832_hexdump(i2c_client_s,buf); |
111 | 116 | ||
112 | 117 | ||
113 | // Leave low power mode: | 118 | // Leave low power mode: |
114 | printk("Bt832: leave low power mode.\n"); | 119 | v4l_err(i2c_client_s,"leave low power mode.\n"); |
115 | buf[0]=BT832_CAM_SETUP0; //0x39 57 | 120 | buf[0]=BT832_CAM_SETUP0; //0x39 57 |
116 | buf[1]=0x08; | 121 | buf[1]=0x08; |
117 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 122 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
118 | printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); | 123 | v4l_err(i2c_client_s,"i2c i/o error LLPM: rc == %d (should be 2)\n",rc); |
119 | 124 | ||
120 | bt832_hexdump(i2c_client_s,buf); | 125 | bt832_hexdump(i2c_client_s,buf); |
121 | 126 | ||
122 | printk("Write 0 tp VPSTATUS\n"); | 127 | v4l_info(i2c_client_s,"Write 0 tp VPSTATUS\n"); |
123 | buf[0]=BT832_VP_STATUS; // Reg.52 | 128 | buf[0]=BT832_VP_STATUS; // Reg.52 |
124 | buf[1]= 0x00; | 129 | buf[1]= 0x00; |
125 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 130 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
126 | printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); | 131 | v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc); |
127 | 132 | ||
128 | bt832_hexdump(i2c_client_s,buf); | 133 | bt832_hexdump(i2c_client_s,buf); |
129 | 134 | ||
130 | 135 | ||
131 | // Enable Output | 136 | // Enable Output |
132 | printk("Enable Output\n"); | 137 | v4l_info(i2c_client_s,"Enable Output\n"); |
133 | buf[0]=BT832_VP_CONTROL1; // Reg.40 | 138 | buf[0]=BT832_VP_CONTROL1; // Reg.40 |
134 | buf[1]= 0x27 & (~0x01); // Default | !skip | 139 | buf[1]= 0x27 & (~0x01); // Default | !skip |
135 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 140 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
136 | printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); | 141 | v4l_err(i2c_client_s,"i2c i/o error EO: rc == %d (should be 2)\n",rc); |
137 | 142 | ||
138 | bt832_hexdump(i2c_client_s,buf); | 143 | bt832_hexdump(i2c_client_s,buf); |
139 | 144 | ||
140 | 145 | ||
141 | // for testing (even works when no camera attached) | 146 | // for testing (even works when no camera attached) |
142 | printk("bt832: *** Generate NTSC M Bars *****\n"); | 147 | v4l_info(i2c_client_s,"*** Generate NTSC M Bars *****\n"); |
143 | buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 | 148 | buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 |
144 | buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally | 149 | buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally |
145 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 150 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
146 | printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); | 151 | v4l_info(i2c_client_s,"i2c i/o error MBAR: rc == %d (should be 2)\n",rc); |
147 | 152 | ||
148 | printk("Bt832: Camera Present: %s\n", | 153 | v4l_info(i2c_client_s,"Camera Present: %s\n", |
149 | (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); | 154 | (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); |
150 | 155 | ||
151 | bt832_hexdump(i2c_client_s,buf); | 156 | bt832_hexdump(i2c_client_s,buf); |
@@ -159,13 +164,9 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) | |||
159 | { | 164 | { |
160 | struct bt832 *t; | 165 | struct bt832 *t; |
161 | 166 | ||
162 | printk("bt832_attach\n"); | ||
163 | |||
164 | client_template.adapter = adap; | 167 | client_template.adapter = adap; |
165 | client_template.addr = addr; | 168 | client_template.addr = addr; |
166 | 169 | ||
167 | printk("bt832: chip found @ 0x%x\n", addr<<1); | ||
168 | |||
169 | if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) | 170 | if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) |
170 | return -ENOMEM; | 171 | return -ENOMEM; |
171 | memset(t,0,sizeof(*t)); | 172 | memset(t,0,sizeof(*t)); |
@@ -173,6 +174,9 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) | |||
173 | i2c_set_clientdata(&t->client, t); | 174 | i2c_set_clientdata(&t->client, t); |
174 | i2c_attach_client(&t->client); | 175 | i2c_attach_client(&t->client); |
175 | 176 | ||
177 | v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1); | ||
178 | |||
179 | |||
176 | if(! bt832_init(&t->client)) { | 180 | if(! bt832_init(&t->client)) { |
177 | bt832_detach(&t->client); | 181 | bt832_detach(&t->client); |
178 | return -1; | 182 | return -1; |
@@ -183,13 +187,8 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) | |||
183 | 187 | ||
184 | static int bt832_probe(struct i2c_adapter *adap) | 188 | static int bt832_probe(struct i2c_adapter *adap) |
185 | { | 189 | { |
186 | #ifdef I2C_CLASS_TV_ANALOG | ||
187 | if (adap->class & I2C_CLASS_TV_ANALOG) | 190 | if (adap->class & I2C_CLASS_TV_ANALOG) |
188 | return i2c_probe(adap, &addr_data, bt832_attach); | 191 | return i2c_probe(adap, &addr_data, bt832_attach); |
189 | #else | ||
190 | if (adap->id == I2C_HW_B_BT848) | ||
191 | return i2c_probe(adap, &addr_data, bt832_attach); | ||
192 | #endif | ||
193 | return 0; | 192 | return 0; |
194 | } | 193 | } |
195 | 194 | ||
@@ -197,7 +196,7 @@ static int bt832_detach(struct i2c_client *client) | |||
197 | { | 196 | { |
198 | struct bt832 *t = i2c_get_clientdata(client); | 197 | struct bt832 *t = i2c_get_clientdata(client); |
199 | 198 | ||
200 | printk("bt832: detach.\n"); | 199 | v4l_info(&t->client,"dettach\n"); |
201 | i2c_detach_client(client); | 200 | i2c_detach_client(client); |
202 | kfree(t); | 201 | kfree(t); |
203 | return 0; | 202 | return 0; |
@@ -208,7 +207,8 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
208 | { | 207 | { |
209 | struct bt832 *t = i2c_get_clientdata(client); | 208 | struct bt832 *t = i2c_get_clientdata(client); |
210 | 209 | ||
211 | printk("bt832: command %x\n",cmd); | 210 | if (debug>1) |
211 | v4l_i2c_print_ioctl(&t->client,cmd); | ||
212 | 212 | ||
213 | switch (cmd) { | 213 | switch (cmd) { |
214 | case BT832_HEXDUMP: { | 214 | case BT832_HEXDUMP: { |
@@ -219,7 +219,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
219 | } | 219 | } |
220 | break; | 220 | break; |
221 | case BT832_REATTACH: | 221 | case BT832_REATTACH: |
222 | printk("bt832: re-attach\n"); | 222 | v4l_info(&t->client,"re-attach\n"); |
223 | i2c_del_driver(&driver); | 223 | i2c_del_driver(&driver); |
224 | i2c_add_driver(&driver); | 224 | i2c_add_driver(&driver); |
225 | break; | 225 | break; |
@@ -231,9 +231,9 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
231 | 231 | ||
232 | static struct i2c_driver driver = { | 232 | static struct i2c_driver driver = { |
233 | .driver = { | 233 | .driver = { |
234 | .name = "i2c bt832 driver", | 234 | .name = "bt832", |
235 | }, | 235 | }, |
236 | .id = -1, /* FIXME */ | 236 | .id = 0, /* FIXME */ |
237 | .attach_adapter = bt832_probe, | 237 | .attach_adapter = bt832_probe, |
238 | .detach_client = bt832_detach, | 238 | .detach_client = bt832_detach, |
239 | .command = bt832_command, | 239 | .command = bt832_command, |
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 012be639aa18..1621ab133d23 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
39 | 39 | ||
40 | #include "bttvp.h" | 40 | #include "bttvp.h" |
41 | #include <media/v4l2-common.h> | ||
41 | 42 | ||
42 | /* fwd decl */ | 43 | /* fwd decl */ |
43 | static void boot_msp34xx(struct bttv *btv, int pin); | 44 | static void boot_msp34xx(struct bttv *btv, int pin); |
@@ -292,6 +293,9 @@ static struct CARD { | |||
292 | /* likely broken, vendor id doesn't match the other magic views ... | 293 | /* likely broken, vendor id doesn't match the other magic views ... |
293 | * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ | 294 | * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ |
294 | 295 | ||
296 | /* Duplicate PCI ID, reconfigure for this board during the eeprom read. | ||
297 | * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ | ||
298 | |||
295 | /* DVB cards (using pci function .1 for mpeg data xfer) */ | 299 | /* DVB cards (using pci function .1 for mpeg data xfer) */ |
296 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, | 300 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, |
297 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | 301 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, |
@@ -2136,7 +2140,6 @@ struct tvcard bttv_tvcards[] = { | |||
2136 | .has_remote = 1, | 2140 | .has_remote = 1, |
2137 | .gpiomask = 0x1b, | 2141 | .gpiomask = 0x1b, |
2138 | .no_gpioirq = 1, | 2142 | .no_gpioirq = 1, |
2139 | .any_irq = 1, | ||
2140 | }, | 2143 | }, |
2141 | [BTTV_BOARD_PV143] = { | 2144 | [BTTV_BOARD_PV143] = { |
2142 | /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ | 2145 | /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ |
@@ -2817,6 +2820,22 @@ struct tvcard bttv_tvcards[] = { | |||
2817 | .tuner_addr = ADDR_UNSET, | 2820 | .tuner_addr = ADDR_UNSET, |
2818 | .has_radio = 1, | 2821 | .has_radio = 1, |
2819 | }, | 2822 | }, |
2823 | /* ---- card 0x8f ---------------------------------- */ | ||
2824 | [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = { | ||
2825 | .name = "Hauppauge ImpactVCB (bt878)", | ||
2826 | .video_inputs = 4, | ||
2827 | .audio_inputs = 0, | ||
2828 | .tuner = -1, | ||
2829 | .svhs = -1, | ||
2830 | .gpiomask = 0x0f, /* old: 7 */ | ||
2831 | .muxsel = { 0, 1, 3, 2}, /* Composite 0-3 */ | ||
2832 | .no_msp34xx = 1, | ||
2833 | .no_tda9875 = 1, | ||
2834 | .no_tda7432 = 1, | ||
2835 | .tuner_type = -1, | ||
2836 | .tuner_addr = ADDR_UNSET, | ||
2837 | .radio_addr = ADDR_UNSET, | ||
2838 | }, | ||
2820 | }; | 2839 | }; |
2821 | 2840 | ||
2822 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2841 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
@@ -3037,26 +3056,33 @@ static void miro_pinnacle_gpio(struct bttv *btv) | |||
3037 | switch (id) { | 3056 | switch (id) { |
3038 | case 1: | 3057 | case 1: |
3039 | info = "PAL / mono"; | 3058 | info = "PAL / mono"; |
3059 | btv->tda9887_conf = TDA9887_INTERCARRIER; | ||
3040 | break; | 3060 | break; |
3041 | case 2: | 3061 | case 2: |
3042 | info = "PAL+SECAM / stereo"; | 3062 | info = "PAL+SECAM / stereo"; |
3043 | btv->has_radio = 1; | 3063 | btv->has_radio = 1; |
3064 | btv->tda9887_conf = TDA9887_QSS; | ||
3044 | break; | 3065 | break; |
3045 | case 3: | 3066 | case 3: |
3046 | info = "NTSC / stereo"; | 3067 | info = "NTSC / stereo"; |
3047 | btv->has_radio = 1; | 3068 | btv->has_radio = 1; |
3069 | btv->tda9887_conf = TDA9887_QSS; | ||
3048 | break; | 3070 | break; |
3049 | case 4: | 3071 | case 4: |
3050 | info = "PAL+SECAM / mono"; | 3072 | info = "PAL+SECAM / mono"; |
3073 | btv->tda9887_conf = TDA9887_QSS; | ||
3051 | break; | 3074 | break; |
3052 | case 5: | 3075 | case 5: |
3053 | info = "NTSC / mono"; | 3076 | info = "NTSC / mono"; |
3077 | btv->tda9887_conf = TDA9887_INTERCARRIER; | ||
3054 | break; | 3078 | break; |
3055 | case 6: | 3079 | case 6: |
3056 | info = "NTSC / stereo"; | 3080 | info = "NTSC / stereo"; |
3081 | btv->tda9887_conf = TDA9887_INTERCARRIER; | ||
3057 | break; | 3082 | break; |
3058 | case 7: | 3083 | case 7: |
3059 | info = "PAL / stereo"; | 3084 | info = "PAL / stereo"; |
3085 | btv->tda9887_conf = TDA9887_INTERCARRIER; | ||
3060 | break; | 3086 | break; |
3061 | default: | 3087 | default: |
3062 | info = "oops: unknown card"; | 3088 | info = "oops: unknown card"; |
@@ -3067,8 +3093,7 @@ static void miro_pinnacle_gpio(struct bttv *btv) | |||
3067 | printk(KERN_INFO | 3093 | printk(KERN_INFO |
3068 | "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", | 3094 | "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", |
3069 | btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); | 3095 | btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); |
3070 | btv->tuner_type = 33; | 3096 | btv->tuner_type = TUNER_MT2032; |
3071 | btv->pinnacle_id = id; | ||
3072 | } | 3097 | } |
3073 | } | 3098 | } |
3074 | 3099 | ||
@@ -3370,9 +3395,9 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3370 | bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); | 3395 | bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); |
3371 | } | 3396 | } |
3372 | 3397 | ||
3373 | if (btv->pinnacle_id != UNSET) { | 3398 | if (btv->tda9887_conf) { |
3374 | bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE, | 3399 | bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG, |
3375 | &btv->pinnacle_id); | 3400 | &btv->tda9887_conf); |
3376 | } | 3401 | } |
3377 | 3402 | ||
3378 | btv->svhs = bttv_tvcards[btv->c.type].svhs; | 3403 | btv->svhs = bttv_tvcards[btv->c.type].svhs; |
@@ -3387,8 +3412,6 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3387 | btv->has_remote=1; | 3412 | btv->has_remote=1; |
3388 | if (!bttv_tvcards[btv->c.type].no_gpioirq) | 3413 | if (!bttv_tvcards[btv->c.type].no_gpioirq) |
3389 | btv->gpioirq=1; | 3414 | btv->gpioirq=1; |
3390 | if (bttv_tvcards[btv->c.type].any_irq) | ||
3391 | btv->any_irq = 1; | ||
3392 | if (bttv_tvcards[btv->c.type].audio_hook) | 3415 | if (bttv_tvcards[btv->c.type].audio_hook) |
3393 | btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; | 3416 | btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; |
3394 | 3417 | ||
@@ -3424,7 +3447,7 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3424 | 3447 | ||
3425 | /* tuner modules */ | 3448 | /* tuner modules */ |
3426 | tda9887 = 0; | 3449 | tda9887 = 0; |
3427 | if (btv->pinnacle_id != UNSET) | 3450 | if (btv->tda9887_conf) |
3428 | tda9887 = 1; | 3451 | tda9887 = 1; |
3429 | if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && | 3452 | if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && |
3430 | bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) | 3453 | bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) |
@@ -3471,6 +3494,21 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) | |||
3471 | tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data); | 3494 | tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data); |
3472 | btv->tuner_type = tv.tuner_type; | 3495 | btv->tuner_type = tv.tuner_type; |
3473 | btv->has_radio = tv.has_radio; | 3496 | btv->has_radio = tv.has_radio; |
3497 | |||
3498 | printk("bttv%d: Hauppauge eeprom indicates model#%d\n", | ||
3499 | btv->c.nr, tv.model); | ||
3500 | |||
3501 | /* | ||
3502 | * Some of the 878 boards have duplicate PCI IDs. Switch the board | ||
3503 | * type based on model #. | ||
3504 | */ | ||
3505 | if(tv.model == 64900) { | ||
3506 | printk("bttv%d: Switching board type from %s to %s\n", | ||
3507 | btv->c.nr, | ||
3508 | bttv_tvcards[btv->c.type].name, | ||
3509 | bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); | ||
3510 | btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; | ||
3511 | } | ||
3474 | } | 3512 | } |
3475 | 3513 | ||
3476 | static int terratec_active_radio_upgrade(struct bttv *btv) | 3514 | static int terratec_active_radio_upgrade(struct bttv *btv) |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 1ddf9ba613ef..0e6970346788 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -34,13 +34,14 @@ | |||
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/kdev_t.h> | 36 | #include <linux/kdev_t.h> |
37 | #include "bttvp.h" | ||
38 | #include <media/v4l2-common.h> | ||
39 | |||
37 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
38 | 41 | ||
39 | #include <asm/io.h> | 42 | #include <asm/io.h> |
40 | #include <asm/byteorder.h> | 43 | #include <asm/byteorder.h> |
41 | 44 | ||
42 | #include "bttvp.h" | ||
43 | |||
44 | #include "rds.h" | 45 | #include "rds.h" |
45 | 46 | ||
46 | 47 | ||
@@ -210,6 +211,9 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
210 | .vdelay = 0x20, | 211 | .vdelay = 0x20, |
211 | .vbipack = 255, | 212 | .vbipack = 255, |
212 | .sram = 0, | 213 | .sram = 0, |
214 | /* ITU-R frame line number of the first VBI line | ||
215 | we can capture, of the first and second field. */ | ||
216 | .vbistart = { 7,320 }, | ||
213 | },{ | 217 | },{ |
214 | .v4l2_id = V4L2_STD_NTSC_M, | 218 | .v4l2_id = V4L2_STD_NTSC_M, |
215 | .name = "NTSC", | 219 | .name = "NTSC", |
@@ -226,6 +230,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
226 | .vdelay = 0x1a, | 230 | .vdelay = 0x1a, |
227 | .vbipack = 144, | 231 | .vbipack = 144, |
228 | .sram = 1, | 232 | .sram = 1, |
233 | .vbistart = { 10, 273 }, | ||
229 | },{ | 234 | },{ |
230 | .v4l2_id = V4L2_STD_SECAM, | 235 | .v4l2_id = V4L2_STD_SECAM, |
231 | .name = "SECAM", | 236 | .name = "SECAM", |
@@ -242,6 +247,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
242 | .vdelay = 0x20, | 247 | .vdelay = 0x20, |
243 | .vbipack = 255, | 248 | .vbipack = 255, |
244 | .sram = 0, /* like PAL, correct? */ | 249 | .sram = 0, /* like PAL, correct? */ |
250 | .vbistart = { 7, 320 }, | ||
245 | },{ | 251 | },{ |
246 | .v4l2_id = V4L2_STD_PAL_Nc, | 252 | .v4l2_id = V4L2_STD_PAL_Nc, |
247 | .name = "PAL-Nc", | 253 | .name = "PAL-Nc", |
@@ -258,6 +264,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
258 | .vdelay = 0x1a, | 264 | .vdelay = 0x1a, |
259 | .vbipack = 144, | 265 | .vbipack = 144, |
260 | .sram = -1, | 266 | .sram = -1, |
267 | .vbistart = { 7, 320 }, | ||
261 | },{ | 268 | },{ |
262 | .v4l2_id = V4L2_STD_PAL_M, | 269 | .v4l2_id = V4L2_STD_PAL_M, |
263 | .name = "PAL-M", | 270 | .name = "PAL-M", |
@@ -274,6 +281,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
274 | .vdelay = 0x1a, | 281 | .vdelay = 0x1a, |
275 | .vbipack = 144, | 282 | .vbipack = 144, |
276 | .sram = -1, | 283 | .sram = -1, |
284 | .vbistart = { 10, 273 }, | ||
277 | },{ | 285 | },{ |
278 | .v4l2_id = V4L2_STD_PAL_N, | 286 | .v4l2_id = V4L2_STD_PAL_N, |
279 | .name = "PAL-N", | 287 | .name = "PAL-N", |
@@ -290,6 +298,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
290 | .vdelay = 0x20, | 298 | .vdelay = 0x20, |
291 | .vbipack = 144, | 299 | .vbipack = 144, |
292 | .sram = -1, | 300 | .sram = -1, |
301 | .vbistart = { 7, 320}, | ||
293 | },{ | 302 | },{ |
294 | .v4l2_id = V4L2_STD_NTSC_M_JP, | 303 | .v4l2_id = V4L2_STD_NTSC_M_JP, |
295 | .name = "NTSC-JP", | 304 | .name = "NTSC-JP", |
@@ -306,6 +315,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
306 | .vdelay = 0x16, | 315 | .vdelay = 0x16, |
307 | .vbipack = 144, | 316 | .vbipack = 144, |
308 | .sram = -1, | 317 | .sram = -1, |
318 | .vbistart = {10, 273}, | ||
309 | },{ | 319 | },{ |
310 | /* that one hopefully works with the strange timing | 320 | /* that one hopefully works with the strange timing |
311 | * which video recorders produce when playing a NTSC | 321 | * which video recorders produce when playing a NTSC |
@@ -326,6 +336,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
326 | .vbipack = 255, | 336 | .vbipack = 255, |
327 | .vtotal = 524, | 337 | .vtotal = 524, |
328 | .sram = -1, | 338 | .sram = -1, |
339 | .vbistart = { 10, 273 }, | ||
329 | } | 340 | } |
330 | }; | 341 | }; |
331 | static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); | 342 | static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); |
@@ -1510,14 +1521,6 @@ static struct videobuf_queue_ops bttv_video_qops = { | |||
1510 | .buf_release = buffer_release, | 1521 | .buf_release = buffer_release, |
1511 | }; | 1522 | }; |
1512 | 1523 | ||
1513 | static const char *v4l1_ioctls[] = { | ||
1514 | "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", | ||
1515 | "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", | ||
1516 | "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", | ||
1517 | "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", | ||
1518 | "SMICROCODE", "GVBIFMT", "SVBIFMT" }; | ||
1519 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
1520 | |||
1521 | static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | 1524 | static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) |
1522 | { | 1525 | { |
1523 | switch (cmd) { | 1526 | switch (cmd) { |
@@ -2206,22 +2209,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2206 | unsigned long flags; | 2209 | unsigned long flags; |
2207 | int retval = 0; | 2210 | int retval = 0; |
2208 | 2211 | ||
2209 | if (bttv_debug > 1) { | 2212 | if (bttv_debug > 1) |
2210 | switch (_IOC_TYPE(cmd)) { | 2213 | v4l_print_ioctl(btv->c.name, cmd); |
2211 | case 'v': | 2214 | |
2212 | printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n", | ||
2213 | btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ? | ||
2214 | v4l1_ioctls[_IOC_NR(cmd)] : "???"); | ||
2215 | break; | ||
2216 | case 'V': | ||
2217 | printk("bttv%d: ioctl 0x%x (v4l2, %s)\n", | ||
2218 | btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]); | ||
2219 | break; | ||
2220 | default: | ||
2221 | printk("bttv%d: ioctl 0x%x (???)\n", | ||
2222 | btv->c.nr, cmd); | ||
2223 | } | ||
2224 | } | ||
2225 | if (btv->errors) | 2215 | if (btv->errors) |
2226 | bttv_reinit_bt848(btv); | 2216 | bttv_reinit_bt848(btv); |
2227 | 2217 | ||
@@ -2570,10 +2560,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2570 | fmt->count[0] = fmt2.fmt.vbi.count[0]; | 2560 | fmt->count[0] = fmt2.fmt.vbi.count[0]; |
2571 | fmt->start[1] = fmt2.fmt.vbi.start[1]; | 2561 | fmt->start[1] = fmt2.fmt.vbi.start[1]; |
2572 | fmt->count[1] = fmt2.fmt.vbi.count[1]; | 2562 | fmt->count[1] = fmt2.fmt.vbi.count[1]; |
2573 | if (fmt2.fmt.vbi.flags & VBI_UNSYNC) | 2563 | if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC) |
2574 | fmt->flags |= V4L2_VBI_UNSYNC; | 2564 | fmt->flags |= VBI_UNSYNC; |
2575 | if (fmt2.fmt.vbi.flags & VBI_INTERLACED) | 2565 | if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED) |
2576 | fmt->flags |= V4L2_VBI_INTERLACED; | 2566 | fmt->flags |= VBI_INTERLACED; |
2577 | return 0; | 2567 | return 0; |
2578 | } | 2568 | } |
2579 | case VIDIOCSVBIFMT: | 2569 | case VIDIOCSVBIFMT: |
@@ -3120,6 +3110,7 @@ static struct file_operations bttv_fops = | |||
3120 | .open = bttv_open, | 3110 | .open = bttv_open, |
3121 | .release = bttv_release, | 3111 | .release = bttv_release, |
3122 | .ioctl = bttv_ioctl, | 3112 | .ioctl = bttv_ioctl, |
3113 | .compat_ioctl = v4l_compat_ioctl32, | ||
3123 | .llseek = no_llseek, | 3114 | .llseek = no_llseek, |
3124 | .read = bttv_read, | 3115 | .read = bttv_read, |
3125 | .mmap = bttv_mmap, | 3116 | .mmap = bttv_mmap, |
@@ -3229,6 +3220,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
3229 | case VIDIOCSFREQ: | 3220 | case VIDIOCSFREQ: |
3230 | case VIDIOCGAUDIO: | 3221 | case VIDIOCGAUDIO: |
3231 | case VIDIOCSAUDIO: | 3222 | case VIDIOCSAUDIO: |
3223 | case VIDIOC_LOG_STATUS: | ||
3232 | return bttv_common_ioctls(btv,cmd,arg); | 3224 | return bttv_common_ioctls(btv,cmd,arg); |
3233 | 3225 | ||
3234 | default: | 3226 | default: |
@@ -3701,8 +3693,8 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3701 | 3693 | ||
3702 | btv=(struct bttv *)dev_id; | 3694 | btv=(struct bttv *)dev_id; |
3703 | 3695 | ||
3704 | if (btv->any_irq) | 3696 | if (btv->custom_irq) |
3705 | handled = bttv_any_irq(&btv->c); | 3697 | handled = btv->custom_irq(btv); |
3706 | 3698 | ||
3707 | count=0; | 3699 | count=0; |
3708 | while (1) { | 3700 | while (1) { |
@@ -3738,9 +3730,9 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3738 | if (astat&BT848_INT_VSYNC) | 3730 | if (astat&BT848_INT_VSYNC) |
3739 | btv->field_count++; | 3731 | btv->field_count++; |
3740 | 3732 | ||
3741 | if (astat & BT848_INT_GPINT) { | 3733 | if ((astat & BT848_INT_GPINT) && btv->remote) { |
3742 | wake_up(&btv->gpioq); | 3734 | wake_up(&btv->gpioq); |
3743 | bttv_gpio_irq(&btv->c); | 3735 | bttv_input_irq(btv); |
3744 | } | 3736 | } |
3745 | 3737 | ||
3746 | if (astat & BT848_INT_I2CDONE) { | 3738 | if (astat & BT848_INT_I2CDONE) { |
@@ -3946,7 +3938,6 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3946 | 3938 | ||
3947 | btv->i2c_rc = -1; | 3939 | btv->i2c_rc = -1; |
3948 | btv->tuner_type = UNSET; | 3940 | btv->tuner_type = UNSET; |
3949 | btv->pinnacle_id = UNSET; | ||
3950 | btv->new_input = UNSET; | 3941 | btv->new_input = UNSET; |
3951 | btv->has_radio=radio[btv->c.nr]; | 3942 | btv->has_radio=radio[btv->c.nr]; |
3952 | 3943 | ||
@@ -4065,11 +4056,11 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4065 | } | 4056 | } |
4066 | 4057 | ||
4067 | /* add subdevices */ | 4058 | /* add subdevices */ |
4068 | if (btv->has_remote) | ||
4069 | bttv_sub_add_device(&btv->c, "remote"); | ||
4070 | if (bttv_tvcards[btv->c.type].has_dvb) | 4059 | if (bttv_tvcards[btv->c.type].has_dvb) |
4071 | bttv_sub_add_device(&btv->c, "dvb"); | 4060 | bttv_sub_add_device(&btv->c, "dvb"); |
4072 | 4061 | ||
4062 | bttv_input_init(btv); | ||
4063 | |||
4073 | /* everything is fine */ | 4064 | /* everything is fine */ |
4074 | bttv_num++; | 4065 | bttv_num++; |
4075 | return 0; | 4066 | return 0; |
@@ -4104,6 +4095,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) | |||
4104 | /* tell gpio modules we are leaving ... */ | 4095 | /* tell gpio modules we are leaving ... */ |
4105 | btv->shutdown=1; | 4096 | btv->shutdown=1; |
4106 | wake_up(&btv->gpioq); | 4097 | wake_up(&btv->gpioq); |
4098 | bttv_input_fini(btv); | ||
4107 | bttv_sub_del_devices(&btv->c); | 4099 | bttv_sub_del_devices(&btv->c); |
4108 | 4100 | ||
4109 | /* unregister i2c_bus + input */ | 4101 | /* unregister i2c_bus + input */ |
@@ -4253,7 +4245,7 @@ static int bttv_init_module(void) | |||
4253 | bttv_check_chipset(); | 4245 | bttv_check_chipset(); |
4254 | 4246 | ||
4255 | bus_register(&bttv_sub_bus_type); | 4247 | bus_register(&bttv_sub_bus_type); |
4256 | return pci_module_init(&bttv_pci_driver); | 4248 | return pci_register_driver(&bttv_pci_driver); |
4257 | } | 4249 | } |
4258 | 4250 | ||
4259 | static void bttv_cleanup_module(void) | 4251 | static void bttv_cleanup_module(void) |
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c index 616a5b7e510c..575ce8b8e714 100644 --- a/drivers/media/video/bttv-gpio.c +++ b/drivers/media/video/bttv-gpio.c | |||
@@ -113,24 +113,6 @@ void bttv_gpio_irq(struct bttv_core *core) | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | int bttv_any_irq(struct bttv_core *core) | ||
117 | { | ||
118 | struct bttv_sub_driver *drv; | ||
119 | struct bttv_sub_device *dev; | ||
120 | struct list_head *item; | ||
121 | int handled = 0; | ||
122 | |||
123 | list_for_each(item,&core->subs) { | ||
124 | dev = list_entry(item,struct bttv_sub_device,list); | ||
125 | drv = to_bttv_sub_drv(dev->dev.driver); | ||
126 | if (drv && drv->any_irq) { | ||
127 | if (drv->any_irq(dev)) | ||
128 | handled = 1; | ||
129 | } | ||
130 | } | ||
131 | return handled; | ||
132 | } | ||
133 | |||
134 | /* ----------------------------------------------------------------------- */ | 116 | /* ----------------------------------------------------------------------- */ |
135 | /* external: sub-driver register/unregister */ | 117 | /* external: sub-driver register/unregister */ |
136 | 118 | ||
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index d6418c023d39..748d630c7fe4 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c | |||
@@ -28,10 +28,11 @@ | |||
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/jiffies.h> | ||
32 | #include <asm/io.h> | ||
33 | 31 | ||
34 | #include "bttvp.h" | 32 | #include "bttvp.h" |
33 | #include <media/v4l2-common.h> | ||
34 | #include <linux/jiffies.h> | ||
35 | #include <asm/io.h> | ||
35 | 36 | ||
36 | static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; | 37 | static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; |
37 | static struct i2c_adapter bttv_i2c_adap_sw_template; | 38 | static struct i2c_adapter bttv_i2c_adap_sw_template; |
@@ -105,10 +106,8 @@ static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { | |||
105 | 106 | ||
106 | static struct i2c_adapter bttv_i2c_adap_sw_template = { | 107 | static struct i2c_adapter bttv_i2c_adap_sw_template = { |
107 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
108 | #ifdef I2C_CLASS_TV_ANALOG | ||
109 | .class = I2C_CLASS_TV_ANALOG, | 109 | .class = I2C_CLASS_TV_ANALOG, |
110 | #endif | 110 | .name = "bttv", |
111 | .name = "bt848", | ||
112 | .id = I2C_HW_B_BT848, | 111 | .id = I2C_HW_B_BT848, |
113 | .client_register = attach_inform, | 112 | .client_register = attach_inform, |
114 | }; | 113 | }; |
@@ -275,10 +274,8 @@ static struct i2c_algorithm bttv_algo = { | |||
275 | }; | 274 | }; |
276 | 275 | ||
277 | static struct i2c_adapter bttv_i2c_adap_hw_template = { | 276 | static struct i2c_adapter bttv_i2c_adap_hw_template = { |
278 | .owner = THIS_MODULE, | 277 | .owner = THIS_MODULE, |
279 | #ifdef I2C_CLASS_TV_ANALOG | ||
280 | .class = I2C_CLASS_TV_ANALOG, | 278 | .class = I2C_CLASS_TV_ANALOG, |
281 | #endif | ||
282 | .name = "bt878", | 279 | .name = "bt878", |
283 | .id = I2C_HW_B_BT848 /* FIXME */, | 280 | .id = I2C_HW_B_BT848 /* FIXME */, |
284 | .algo = &bttv_algo, | 281 | .algo = &bttv_algo, |
@@ -441,12 +438,10 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
441 | i2c_set_adapdata(&btv->c.i2c_adap, btv); | 438 | i2c_set_adapdata(&btv->c.i2c_adap, btv); |
442 | btv->i2c_client.adapter = &btv->c.i2c_adap; | 439 | btv->i2c_client.adapter = &btv->c.i2c_adap; |
443 | 440 | ||
444 | #ifdef I2C_CLASS_TV_ANALOG | ||
445 | if (bttv_tvcards[btv->c.type].no_video) | 441 | if (bttv_tvcards[btv->c.type].no_video) |
446 | btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; | 442 | btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; |
447 | if (bttv_tvcards[btv->c.type].has_dvb) | 443 | if (bttv_tvcards[btv->c.type].has_dvb) |
448 | btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; | 444 | btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; |
449 | #endif | ||
450 | 445 | ||
451 | if (btv->use_i2c_hw) { | 446 | if (btv->use_i2c_hw) { |
452 | btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); | 447 | btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); |
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/bttv-input.c index de1385e5d05e..12197f1b2757 100644 --- a/drivers/media/video/ir-kbd-gpio.c +++ b/drivers/media/video/bttv-input.c | |||
@@ -24,11 +24,9 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/pci.h> | ||
28 | |||
29 | #include <media/ir-common.h> | ||
30 | 27 | ||
31 | #include "bttv.h" | 28 | #include "bttv.h" |
29 | #include "bttvp.h" | ||
32 | 30 | ||
33 | /* ---------------------------------------------------------------------- */ | 31 | /* ---------------------------------------------------------------------- */ |
34 | 32 | ||
@@ -156,9 +154,6 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { | |||
156 | 154 | ||
157 | /* ---------------------------------------------------------------------- */ | 155 | /* ---------------------------------------------------------------------- */ |
158 | 156 | ||
159 | /* Ricardo Cerqueira <v4l@cerqueira.org> */ | ||
160 | /* Weird matching, since the remote has "uncommon" keys */ | ||
161 | |||
162 | static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { | 157 | static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { |
163 | 158 | ||
164 | [ 30 ] = KEY_POWER, // power | 159 | [ 30 ] = KEY_POWER, // power |
@@ -279,34 +274,6 @@ static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { | |||
279 | [0x36] = KEY_PC | 274 | [0x36] = KEY_PC |
280 | }; | 275 | }; |
281 | 276 | ||
282 | struct IR { | ||
283 | struct bttv_sub_device *sub; | ||
284 | struct input_dev *input; | ||
285 | struct ir_input_state ir; | ||
286 | char name[32]; | ||
287 | char phys[32]; | ||
288 | |||
289 | /* Usual gpio signalling */ | ||
290 | |||
291 | u32 mask_keycode; | ||
292 | u32 mask_keydown; | ||
293 | u32 mask_keyup; | ||
294 | u32 polling; | ||
295 | u32 last_gpio; | ||
296 | struct work_struct work; | ||
297 | struct timer_list timer; | ||
298 | |||
299 | /* RC5 gpio */ | ||
300 | u32 rc5_gpio; | ||
301 | struct timer_list timer_end; /* timer_end for code completion */ | ||
302 | struct timer_list timer_keyup; /* timer_end for key release */ | ||
303 | u32 last_rc5; /* last good rc5 code */ | ||
304 | u32 last_bit; /* last raw bit seen */ | ||
305 | u32 code; /* raw code under construction */ | ||
306 | struct timeval base_time; /* time of last seen code */ | ||
307 | int active; /* building raw code */ | ||
308 | }; | ||
309 | |||
310 | static int debug; | 277 | static int debug; |
311 | module_param(debug, int, 0644); /* debug level (0,1,2) */ | 278 | module_param(debug, int, 0644); /* debug level (0,1,2) */ |
312 | static int repeat_delay = 500; | 279 | static int repeat_delay = 500; |
@@ -314,31 +281,17 @@ module_param(repeat_delay, int, 0644); | |||
314 | static int repeat_period = 33; | 281 | static int repeat_period = 33; |
315 | module_param(repeat_period, int, 0644); | 282 | module_param(repeat_period, int, 0644); |
316 | 283 | ||
317 | #define DEVNAME "ir-kbd-gpio" | 284 | #define DEVNAME "bttv-input" |
318 | #define dprintk(fmt, arg...) if (debug) \ | ||
319 | printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) | ||
320 | |||
321 | static void ir_irq(struct bttv_sub_device *sub); | ||
322 | static int ir_probe(struct device *dev); | ||
323 | static int ir_remove(struct device *dev); | ||
324 | |||
325 | static struct bttv_sub_driver driver = { | ||
326 | .drv = { | ||
327 | .name = DEVNAME, | ||
328 | .probe = ir_probe, | ||
329 | .remove = ir_remove, | ||
330 | }, | ||
331 | .gpio_irq = ir_irq, | ||
332 | }; | ||
333 | 285 | ||
334 | /* ---------------------------------------------------------------------- */ | 286 | /* ---------------------------------------------------------------------- */ |
335 | 287 | ||
336 | static void ir_handle_key(struct IR *ir) | 288 | static void ir_handle_key(struct bttv *btv) |
337 | { | 289 | { |
290 | struct bttv_ir *ir = btv->remote; | ||
338 | u32 gpio,data; | 291 | u32 gpio,data; |
339 | 292 | ||
340 | /* read gpio value */ | 293 | /* read gpio value */ |
341 | gpio = bttv_gpio_read(ir->sub->core); | 294 | gpio = bttv_gpio_read(&btv->c); |
342 | if (ir->polling) { | 295 | if (ir->polling) { |
343 | if (ir->last_gpio == gpio) | 296 | if (ir->last_gpio == gpio) |
344 | return; | 297 | return; |
@@ -347,56 +300,36 @@ static void ir_handle_key(struct IR *ir) | |||
347 | 300 | ||
348 | /* extract data */ | 301 | /* extract data */ |
349 | data = ir_extract_bits(gpio, ir->mask_keycode); | 302 | data = ir_extract_bits(gpio, ir->mask_keycode); |
350 | dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n", | 303 | dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n", |
351 | gpio, data, | 304 | gpio, data, |
352 | ir->polling ? "poll" : "irq", | 305 | ir->polling ? "poll" : "irq", |
353 | (gpio & ir->mask_keydown) ? " down" : "", | 306 | (gpio & ir->mask_keydown) ? " down" : "", |
354 | (gpio & ir->mask_keyup) ? " up" : ""); | 307 | (gpio & ir->mask_keyup) ? " up" : ""); |
355 | 308 | ||
356 | if (ir->mask_keydown) { | 309 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || |
357 | /* bit set on keydown */ | 310 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { |
358 | if (gpio & ir->mask_keydown) { | 311 | ir_input_keydown(ir->dev,&ir->ir,data,data); |
359 | ir_input_keydown(ir->input, &ir->ir, data, data); | ||
360 | } else { | ||
361 | ir_input_nokey(ir->input, &ir->ir); | ||
362 | } | ||
363 | |||
364 | } else if (ir->mask_keyup) { | ||
365 | /* bit cleared on keydown */ | ||
366 | if (0 == (gpio & ir->mask_keyup)) { | ||
367 | ir_input_keydown(ir->input, &ir->ir, data, data); | ||
368 | } else { | ||
369 | ir_input_nokey(ir->input, &ir->ir); | ||
370 | } | ||
371 | |||
372 | } else { | 312 | } else { |
373 | /* can't disturgissh keydown/up :-/ */ | 313 | ir_input_nokey(ir->dev,&ir->ir); |
374 | ir_input_keydown(ir->input, &ir->ir, data, data); | ||
375 | ir_input_nokey(ir->input, &ir->ir); | ||
376 | } | 314 | } |
377 | } | ||
378 | |||
379 | static void ir_irq(struct bttv_sub_device *sub) | ||
380 | { | ||
381 | struct IR *ir = dev_get_drvdata(&sub->dev); | ||
382 | 315 | ||
383 | if (!ir->polling) | ||
384 | ir_handle_key(ir); | ||
385 | } | 316 | } |
386 | 317 | ||
387 | static void ir_timer(unsigned long data) | 318 | void bttv_input_irq(struct bttv *btv) |
388 | { | 319 | { |
389 | struct IR *ir = (struct IR*)data; | 320 | struct bttv_ir *ir = btv->remote; |
390 | 321 | ||
391 | schedule_work(&ir->work); | 322 | if (!ir->polling) |
323 | ir_handle_key(btv); | ||
392 | } | 324 | } |
393 | 325 | ||
394 | static void ir_work(void *data) | 326 | static void bttv_input_timer(unsigned long data) |
395 | { | 327 | { |
396 | struct IR *ir = data; | 328 | struct bttv *btv = (struct bttv*)data; |
329 | struct bttv_ir *ir = btv->remote; | ||
397 | unsigned long timeout; | 330 | unsigned long timeout; |
398 | 331 | ||
399 | ir_handle_key(ir); | 332 | ir_handle_key(btv); |
400 | timeout = jiffies + (ir->polling * HZ / 1000); | 333 | timeout = jiffies + (ir->polling * HZ / 1000); |
401 | mod_timer(&ir->timer, timeout); | 334 | mod_timer(&ir->timer, timeout); |
402 | } | 335 | } |
@@ -435,26 +368,26 @@ static u32 rc5_decode(unsigned int code) | |||
435 | rc5 |= 1; | 368 | rc5 |= 1; |
436 | break; | 369 | break; |
437 | case 3: | 370 | case 3: |
438 | dprintk("bad code: %x\n", org_code); | 371 | dprintk(KERN_WARNING "bad code: %x\n", org_code); |
439 | return 0; | 372 | return 0; |
440 | } | 373 | } |
441 | } | 374 | } |
442 | dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | 375 | dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " |
443 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | 376 | "instr=%x\n", rc5, org_code, RC5_START(rc5), |
444 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | 377 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); |
445 | return rc5; | 378 | return rc5; |
446 | } | 379 | } |
447 | 380 | ||
448 | static int ir_rc5_irq(struct bttv_sub_device *sub) | 381 | static int bttv_rc5_irq(struct bttv *btv) |
449 | { | 382 | { |
450 | struct IR *ir = dev_get_drvdata(&sub->dev); | 383 | struct bttv_ir *ir = btv->remote; |
451 | struct timeval tv; | 384 | struct timeval tv; |
452 | u32 gpio; | 385 | u32 gpio; |
453 | u32 gap; | 386 | u32 gap; |
454 | unsigned long current_jiffies, timeout; | 387 | unsigned long current_jiffies, timeout; |
455 | 388 | ||
456 | /* read gpio port */ | 389 | /* read gpio port */ |
457 | gpio = bttv_gpio_read(ir->sub->core); | 390 | gpio = bttv_gpio_read(&btv->c); |
458 | 391 | ||
459 | /* remote IRQ? */ | 392 | /* remote IRQ? */ |
460 | if (!(gpio & 0x20)) | 393 | if (!(gpio & 0x20)) |
@@ -493,14 +426,15 @@ static int ir_rc5_irq(struct bttv_sub_device *sub) | |||
493 | } | 426 | } |
494 | 427 | ||
495 | /* toggle GPIO pin 4 to reset the irq */ | 428 | /* toggle GPIO pin 4 to reset the irq */ |
496 | bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); | 429 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); |
497 | bttv_gpio_write(ir->sub->core, gpio | (1 << 4)); | 430 | bttv_gpio_write(&btv->c, gpio | (1 << 4)); |
498 | return 1; | 431 | return 1; |
499 | } | 432 | } |
500 | 433 | ||
501 | static void ir_rc5_timer_end(unsigned long data) | 434 | |
435 | static void bttv_rc5_timer_end(unsigned long data) | ||
502 | { | 436 | { |
503 | struct IR *ir = (struct IR *)data; | 437 | struct bttv_ir *ir = (struct bttv_ir *)data; |
504 | struct timeval tv; | 438 | struct timeval tv; |
505 | unsigned long current_jiffies, timeout; | 439 | unsigned long current_jiffies, timeout; |
506 | u32 gap; | 440 | u32 gap; |
@@ -519,20 +453,20 @@ static void ir_rc5_timer_end(unsigned long data) | |||
519 | 453 | ||
520 | /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ | 454 | /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ |
521 | if (gap < 28000) { | 455 | if (gap < 28000) { |
522 | dprintk("spurious timer_end\n"); | 456 | dprintk(KERN_WARNING "spurious timer_end\n"); |
523 | return; | 457 | return; |
524 | } | 458 | } |
525 | 459 | ||
526 | ir->active = 0; | 460 | ir->active = 0; |
527 | if (ir->last_bit < 20) { | 461 | if (ir->last_bit < 20) { |
528 | /* ignore spurious codes (caused by light/other remotes) */ | 462 | /* ignore spurious codes (caused by light/other remotes) */ |
529 | dprintk("short code: %x\n", ir->code); | 463 | dprintk(KERN_WARNING "short code: %x\n", ir->code); |
530 | } else { | 464 | } else { |
531 | u32 rc5 = rc5_decode(ir->code); | 465 | u32 rc5 = rc5_decode(ir->code); |
532 | 466 | ||
533 | /* two start bits? */ | 467 | /* two start bits? */ |
534 | if (RC5_START(rc5) != 3) { | 468 | if (RC5_START(rc5) != 3) { |
535 | dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5)); | 469 | dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5)); |
536 | 470 | ||
537 | /* right address? */ | 471 | /* right address? */ |
538 | } else if (RC5_ADDR(rc5) == 0x0) { | 472 | } else if (RC5_ADDR(rc5) == 0x0) { |
@@ -542,10 +476,10 @@ static void ir_rc5_timer_end(unsigned long data) | |||
542 | /* Good code, decide if repeat/repress */ | 476 | /* Good code, decide if repeat/repress */ |
543 | if (toggle != RC5_TOGGLE(ir->last_rc5) || | 477 | if (toggle != RC5_TOGGLE(ir->last_rc5) || |
544 | instr != RC5_INSTR(ir->last_rc5)) { | 478 | instr != RC5_INSTR(ir->last_rc5)) { |
545 | dprintk("instruction %x, toggle %x\n", instr, | 479 | dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr, |
546 | toggle); | 480 | toggle); |
547 | ir_input_nokey(ir->input, &ir->ir); | 481 | ir_input_nokey(ir->dev, &ir->ir); |
548 | ir_input_keydown(ir->input, &ir->ir, instr, | 482 | ir_input_keydown(ir->dev, &ir->ir, instr, |
549 | instr); | 483 | instr); |
550 | } | 484 | } |
551 | 485 | ||
@@ -560,34 +494,37 @@ static void ir_rc5_timer_end(unsigned long data) | |||
560 | } | 494 | } |
561 | } | 495 | } |
562 | 496 | ||
563 | static void ir_rc5_timer_keyup(unsigned long data) | 497 | static void bttv_rc5_timer_keyup(unsigned long data) |
564 | { | 498 | { |
565 | struct IR *ir = (struct IR *)data; | 499 | struct bttv_ir *ir = (struct bttv_ir *)data; |
566 | 500 | ||
567 | dprintk("key released\n"); | 501 | dprintk(KERN_DEBUG "key released\n"); |
568 | ir_input_nokey(ir->input, &ir->ir); | 502 | ir_input_nokey(ir->dev, &ir->ir); |
569 | } | 503 | } |
570 | 504 | ||
571 | /* ---------------------------------------------------------------------- */ | 505 | /* ---------------------------------------------------------------------- */ |
572 | 506 | ||
573 | static int ir_probe(struct device *dev) | 507 | int bttv_input_init(struct bttv *btv) |
574 | { | 508 | { |
575 | struct bttv_sub_device *sub = to_bttv_sub_dev(dev); | 509 | struct bttv_ir *ir; |
576 | struct IR *ir; | ||
577 | struct input_dev *input_dev; | ||
578 | IR_KEYTAB_TYPE *ir_codes = NULL; | 510 | IR_KEYTAB_TYPE *ir_codes = NULL; |
511 | struct input_dev *input_dev; | ||
579 | int ir_type = IR_TYPE_OTHER; | 512 | int ir_type = IR_TYPE_OTHER; |
580 | 513 | ||
581 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 514 | if (!btv->has_remote) |
515 | return -ENODEV; | ||
516 | |||
517 | ir = kzalloc(sizeof(*ir),GFP_KERNEL); | ||
582 | input_dev = input_allocate_device(); | 518 | input_dev = input_allocate_device(); |
583 | if (!ir || !input_dev) { | 519 | if (!ir || !input_dev) { |
584 | kfree(ir); | 520 | kfree(ir); |
585 | input_free_device(input_dev); | 521 | input_free_device(input_dev); |
586 | return -ENOMEM; | 522 | return -ENOMEM; |
587 | } | 523 | } |
524 | memset(ir,0,sizeof(*ir)); | ||
588 | 525 | ||
589 | /* detect & configure */ | 526 | /* detect & configure */ |
590 | switch (sub->core->type) { | 527 | switch (btv->c.type) { |
591 | case BTTV_BOARD_AVERMEDIA: | 528 | case BTTV_BOARD_AVERMEDIA: |
592 | case BTTV_BOARD_AVPHONE98: | 529 | case BTTV_BOARD_AVPHONE98: |
593 | case BTTV_BOARD_AVERMEDIA98: | 530 | case BTTV_BOARD_AVERMEDIA98: |
@@ -643,12 +580,12 @@ static int ir_probe(struct device *dev) | |||
643 | break; | 580 | break; |
644 | case BTTV_BOARD_NEBULA_DIGITV: | 581 | case BTTV_BOARD_NEBULA_DIGITV: |
645 | ir_codes = ir_codes_nebula; | 582 | ir_codes = ir_codes_nebula; |
646 | driver.any_irq = ir_rc5_irq; | 583 | btv->custom_irq = bttv_rc5_irq; |
647 | driver.gpio_irq = NULL; | ||
648 | ir->rc5_gpio = 1; | 584 | ir->rc5_gpio = 1; |
649 | break; | 585 | break; |
650 | } | 586 | } |
651 | if (NULL == ir_codes) { | 587 | if (NULL == ir_codes) { |
588 | dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type); | ||
652 | kfree(ir); | 589 | kfree(ir); |
653 | input_free_device(input_dev); | 590 | input_free_device(input_dev); |
654 | return -ENODEV; | 591 | return -ENODEV; |
@@ -657,109 +594,92 @@ static int ir_probe(struct device *dev) | |||
657 | if (ir->rc5_gpio) { | 594 | if (ir->rc5_gpio) { |
658 | u32 gpio; | 595 | u32 gpio; |
659 | /* enable remote irq */ | 596 | /* enable remote irq */ |
660 | bttv_gpio_inout(sub->core, (1 << 4), 1 << 4); | 597 | bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); |
661 | gpio = bttv_gpio_read(sub->core); | 598 | gpio = bttv_gpio_read(&btv->c); |
662 | bttv_gpio_write(sub->core, gpio & ~(1 << 4)); | 599 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); |
663 | bttv_gpio_write(sub->core, gpio | (1 << 4)); | 600 | bttv_gpio_write(&btv->c, gpio | (1 << 4)); |
664 | } else { | 601 | } else { |
665 | /* init hardware-specific stuff */ | 602 | /* init hardware-specific stuff */ |
666 | bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0); | 603 | bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0); |
667 | } | 604 | } |
668 | 605 | ||
669 | /* init input device */ | 606 | /* init input device */ |
607 | ir->dev = input_dev; | ||
608 | |||
670 | snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", | 609 | snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", |
671 | sub->core->type); | 610 | btv->c.type); |
672 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 611 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
673 | pci_name(sub->core->pci)); | 612 | pci_name(btv->c.pci)); |
674 | 613 | ||
675 | ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 614 | ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); |
676 | input_dev->name = ir->name; | 615 | input_dev->name = ir->name; |
677 | input_dev->phys = ir->phys; | 616 | input_dev->phys = ir->phys; |
678 | input_dev->id.bustype = BUS_PCI; | 617 | input_dev->id.bustype = BUS_PCI; |
679 | input_dev->id.version = 1; | 618 | input_dev->id.version = 1; |
680 | if (sub->core->pci->subsystem_vendor) { | 619 | if (btv->c.pci->subsystem_vendor) { |
681 | input_dev->id.vendor = sub->core->pci->subsystem_vendor; | 620 | input_dev->id.vendor = btv->c.pci->subsystem_vendor; |
682 | input_dev->id.product = sub->core->pci->subsystem_device; | 621 | input_dev->id.product = btv->c.pci->subsystem_device; |
683 | } else { | 622 | } else { |
684 | input_dev->id.vendor = sub->core->pci->vendor; | 623 | input_dev->id.vendor = btv->c.pci->vendor; |
685 | input_dev->id.product = sub->core->pci->device; | 624 | input_dev->id.product = btv->c.pci->device; |
686 | } | 625 | } |
687 | input_dev->cdev.dev = &sub->core->pci->dev; | 626 | input_dev->cdev.dev = &btv->c.pci->dev; |
688 | |||
689 | ir->input = input_dev; | ||
690 | ir->sub = sub; | ||
691 | 627 | ||
628 | btv->remote = ir; | ||
692 | if (ir->polling) { | 629 | if (ir->polling) { |
693 | INIT_WORK(&ir->work, ir_work, ir); | ||
694 | init_timer(&ir->timer); | 630 | init_timer(&ir->timer); |
695 | ir->timer.function = ir_timer; | 631 | ir->timer.function = bttv_input_timer; |
696 | ir->timer.data = (unsigned long)ir; | 632 | ir->timer.data = (unsigned long)btv; |
697 | schedule_work(&ir->work); | 633 | ir->timer.expires = jiffies + HZ; |
634 | add_timer(&ir->timer); | ||
698 | } else if (ir->rc5_gpio) { | 635 | } else if (ir->rc5_gpio) { |
699 | /* set timer_end for code completion */ | 636 | /* set timer_end for code completion */ |
700 | init_timer(&ir->timer_end); | 637 | init_timer(&ir->timer_end); |
701 | ir->timer_end.function = ir_rc5_timer_end; | 638 | ir->timer_end.function = bttv_rc5_timer_end; |
702 | ir->timer_end.data = (unsigned long)ir; | 639 | ir->timer_end.data = (unsigned long)ir; |
703 | 640 | ||
704 | init_timer(&ir->timer_keyup); | 641 | init_timer(&ir->timer_keyup); |
705 | ir->timer_keyup.function = ir_rc5_timer_keyup; | 642 | ir->timer_keyup.function = bttv_rc5_timer_keyup; |
706 | ir->timer_keyup.data = (unsigned long)ir; | 643 | ir->timer_keyup.data = (unsigned long)ir; |
707 | } | 644 | } |
708 | 645 | ||
709 | /* all done */ | 646 | /* all done */ |
710 | dev_set_drvdata(dev, ir); | 647 | input_register_device(btv->remote->dev); |
711 | input_register_device(ir->input); | 648 | printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys); |
712 | 649 | ||
713 | /* the remote isn't as bouncy as a keyboard */ | 650 | /* the remote isn't as bouncy as a keyboard */ |
714 | ir->input->rep[REP_DELAY] = repeat_delay; | 651 | ir->dev->rep[REP_DELAY] = repeat_delay; |
715 | ir->input->rep[REP_PERIOD] = repeat_period; | 652 | ir->dev->rep[REP_PERIOD] = repeat_period; |
716 | 653 | ||
717 | return 0; | 654 | return 0; |
718 | } | 655 | } |
719 | 656 | ||
720 | static int ir_remove(struct device *dev) | 657 | void bttv_input_fini(struct bttv *btv) |
721 | { | 658 | { |
722 | struct IR *ir = dev_get_drvdata(dev); | 659 | if (btv->remote == NULL) |
660 | return; | ||
723 | 661 | ||
724 | if (ir->polling) { | 662 | if (btv->remote->polling) { |
725 | del_timer(&ir->timer); | 663 | del_timer_sync(&btv->remote->timer); |
726 | flush_scheduled_work(); | 664 | flush_scheduled_work(); |
727 | } | 665 | } |
728 | 666 | ||
729 | if (ir->rc5_gpio) { | 667 | |
668 | if (btv->remote->rc5_gpio) { | ||
730 | u32 gpio; | 669 | u32 gpio; |
731 | 670 | ||
732 | del_timer(&ir->timer_end); | 671 | del_timer_sync(&btv->remote->timer_end); |
733 | flush_scheduled_work(); | 672 | flush_scheduled_work(); |
734 | 673 | ||
735 | gpio = bttv_gpio_read(ir->sub->core); | 674 | gpio = bttv_gpio_read(&btv->c); |
736 | bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); | 675 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); |
737 | } | 676 | } |
738 | 677 | ||
739 | input_unregister_device(ir->input); | 678 | input_unregister_device(btv->remote->dev); |
740 | kfree(ir); | 679 | kfree(btv->remote); |
741 | return 0; | 680 | btv->remote = NULL; |
742 | } | ||
743 | |||
744 | /* ---------------------------------------------------------------------- */ | ||
745 | |||
746 | MODULE_AUTHOR("Gerd Knorr, Pavel Machek"); | ||
747 | MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls"); | ||
748 | MODULE_LICENSE("GPL"); | ||
749 | |||
750 | static int ir_init(void) | ||
751 | { | ||
752 | return bttv_sub_register(&driver, "remote"); | ||
753 | } | 681 | } |
754 | 682 | ||
755 | static void ir_fini(void) | ||
756 | { | ||
757 | bttv_sub_unregister(&driver); | ||
758 | } | ||
759 | |||
760 | module_init(ir_init); | ||
761 | module_exit(ir_fini); | ||
762 | |||
763 | 683 | ||
764 | /* | 684 | /* |
765 | * Local variables: | 685 | * Local variables: |
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c index f4f58c60f152..72afdd64b882 100644 --- a/drivers/media/video/bttv-vbi.c +++ b/drivers/media/video/bttv-vbi.c | |||
@@ -31,6 +31,12 @@ | |||
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include "bttvp.h" | 32 | #include "bttvp.h" |
33 | 33 | ||
34 | /* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate: | ||
35 | bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC | ||
36 | HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge | ||
37 | of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */ | ||
38 | #define VBI_OFFSET ((64 + 0) * 2) | ||
39 | |||
34 | #define VBI_DEFLINES 16 | 40 | #define VBI_DEFLINES 16 |
35 | #define VBI_MAXLINES 32 | 41 | #define VBI_MAXLINES 32 |
36 | 42 | ||
@@ -163,40 +169,30 @@ void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) | |||
163 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 169 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) |
164 | { | 170 | { |
165 | const struct bttv_tvnorm *tvnorm; | 171 | const struct bttv_tvnorm *tvnorm; |
166 | u32 start0,start1; | 172 | s64 count0,count1,count; |
167 | s32 count0,count1,count; | ||
168 | 173 | ||
169 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | 174 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; |
170 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 175 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; |
171 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | 176 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; |
172 | f->fmt.vbi.samples_per_line = 2048; | 177 | f->fmt.vbi.samples_per_line = 2048; |
173 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 178 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
174 | f->fmt.vbi.offset = 244; | 179 | f->fmt.vbi.offset = VBI_OFFSET; |
175 | f->fmt.vbi.flags = 0; | 180 | f->fmt.vbi.flags = 0; |
176 | switch (fh->btv->tvnorm) { | ||
177 | case 1: /* NTSC */ | ||
178 | start0 = 10; | ||
179 | start1 = 273; | ||
180 | break; | ||
181 | case 0: /* PAL */ | ||
182 | case 2: /* SECAM */ | ||
183 | default: | ||
184 | start0 = 7; | ||
185 | start1 = 320; | ||
186 | } | ||
187 | 181 | ||
188 | count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0; | 182 | /* s64 to prevent overflow. */ |
189 | count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1; | 183 | count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0] |
190 | count = max(count0,count1); | 184 | - tvnorm->vbistart[0]; |
191 | if (count > VBI_MAXLINES) | 185 | count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1] |
192 | count = VBI_MAXLINES; | 186 | - tvnorm->vbistart[1]; |
193 | if (count < 1) | 187 | count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES); |
194 | count = 1; | ||
195 | 188 | ||
196 | f->fmt.vbi.start[0] = start0; | 189 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; |
197 | f->fmt.vbi.start[1] = start1; | 190 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; |
198 | f->fmt.vbi.count[0] = count; | 191 | f->fmt.vbi.count[0] = count; |
199 | f->fmt.vbi.count[1] = count; | 192 | f->fmt.vbi.count[1] = count; |
193 | |||
194 | f->fmt.vbi.reserved[0] = 0; | ||
195 | f->fmt.vbi.reserved[1] = 0; | ||
200 | } | 196 | } |
201 | 197 | ||
202 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 198 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) |
@@ -209,21 +205,12 @@ void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) | |||
209 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | 205 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; |
210 | f->fmt.vbi.samples_per_line = 2048; | 206 | f->fmt.vbi.samples_per_line = 2048; |
211 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 207 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
212 | f->fmt.vbi.offset = 244; | 208 | f->fmt.vbi.offset = VBI_OFFSET; |
209 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | ||
210 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | ||
213 | f->fmt.vbi.count[0] = fh->lines; | 211 | f->fmt.vbi.count[0] = fh->lines; |
214 | f->fmt.vbi.count[1] = fh->lines; | 212 | f->fmt.vbi.count[1] = fh->lines; |
215 | f->fmt.vbi.flags = 0; | 213 | f->fmt.vbi.flags = 0; |
216 | switch (fh->btv->tvnorm) { | ||
217 | case 1: /* NTSC */ | ||
218 | f->fmt.vbi.start[0] = 10; | ||
219 | f->fmt.vbi.start[1] = 273; | ||
220 | break; | ||
221 | case 0: /* PAL */ | ||
222 | case 2: /* SECAM */ | ||
223 | default: | ||
224 | f->fmt.vbi.start[0] = 7; | ||
225 | f->fmt.vbi.start[1] = 319; | ||
226 | } | ||
227 | } | 214 | } |
228 | 215 | ||
229 | /* ----------------------------------------------------------------------- */ | 216 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index 93298f06e019..9feaa6bab207 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include <linux/videodev.h> | 17 | #include <linux/videodev.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <media/ir-common.h> | ||
20 | #include <media/ir-kbd-i2c.h> | ||
19 | 21 | ||
20 | /* ---------------------------------------------------------- */ | 22 | /* ---------------------------------------------------------- */ |
21 | /* exported by bttv-cards.c */ | 23 | /* exported by bttv-cards.c */ |
@@ -163,6 +165,7 @@ | |||
163 | #define BTTV_BOARD_OSPREY440 0x8c | 165 | #define BTTV_BOARD_OSPREY440 0x8c |
164 | #define BTTV_BOARD_ASOUND_SKYEYE 0x8d | 166 | #define BTTV_BOARD_ASOUND_SKYEYE 0x8d |
165 | #define BTTV_BOARD_SABRENT_TVFM 0x8e | 167 | #define BTTV_BOARD_SABRENT_TVFM 0x8e |
168 | #define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f | ||
166 | 169 | ||
167 | /* i2c address list */ | 170 | /* i2c address list */ |
168 | #define I2C_TSA5522 0xc2 | 171 | #define I2C_TSA5522 0xc2 |
@@ -210,6 +213,34 @@ struct bttv_core { | |||
210 | 213 | ||
211 | struct bttv; | 214 | struct bttv; |
212 | 215 | ||
216 | |||
217 | struct bttv_ir { | ||
218 | struct input_dev *dev; | ||
219 | struct ir_input_state ir; | ||
220 | char name[32]; | ||
221 | char phys[32]; | ||
222 | |||
223 | /* Usual gpio signalling */ | ||
224 | |||
225 | u32 mask_keycode; | ||
226 | u32 mask_keydown; | ||
227 | u32 mask_keyup; | ||
228 | u32 polling; | ||
229 | u32 last_gpio; | ||
230 | struct work_struct work; | ||
231 | struct timer_list timer; | ||
232 | |||
233 | /* RC5 gpio */ | ||
234 | u32 rc5_gpio; | ||
235 | struct timer_list timer_end; /* timer_end for code completion */ | ||
236 | struct timer_list timer_keyup; /* timer_end for key release */ | ||
237 | u32 last_rc5; /* last good rc5 code */ | ||
238 | u32 last_bit; /* last raw bit seen */ | ||
239 | u32 code; /* raw code under construction */ | ||
240 | struct timeval base_time; /* time of last seen code */ | ||
241 | int active; /* building raw code */ | ||
242 | }; | ||
243 | |||
213 | struct tvcard | 244 | struct tvcard |
214 | { | 245 | { |
215 | char *name; | 246 | char *name; |
@@ -235,7 +266,6 @@ struct tvcard | |||
235 | unsigned int has_dvb:1; | 266 | unsigned int has_dvb:1; |
236 | unsigned int has_remote:1; | 267 | unsigned int has_remote:1; |
237 | unsigned int no_gpioirq:1; | 268 | unsigned int no_gpioirq:1; |
238 | unsigned int any_irq:1; | ||
239 | 269 | ||
240 | /* other settings */ | 270 | /* other settings */ |
241 | unsigned int pll; | 271 | unsigned int pll; |
@@ -335,7 +365,6 @@ struct bttv_sub_driver { | |||
335 | struct device_driver drv; | 365 | struct device_driver drv; |
336 | char wanted[BUS_ID_SIZE]; | 366 | char wanted[BUS_ID_SIZE]; |
337 | void (*gpio_irq)(struct bttv_sub_device *sub); | 367 | void (*gpio_irq)(struct bttv_sub_device *sub); |
338 | int (*any_irq)(struct bttv_sub_device *sub); | ||
339 | }; | 368 | }; |
340 | #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) | 369 | #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) |
341 | 370 | ||
@@ -363,6 +392,10 @@ extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, | |||
363 | unsigned char b2, int both); | 392 | unsigned char b2, int both); |
364 | extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); | 393 | extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); |
365 | 394 | ||
395 | extern int bttv_input_init(struct bttv *dev); | ||
396 | extern void bttv_input_fini(struct bttv *dev); | ||
397 | extern void bttv_input_irq(struct bttv *dev); | ||
398 | |||
366 | #endif /* _BTTV_H_ */ | 399 | #endif /* _BTTV_H_ */ |
367 | /* | 400 | /* |
368 | * Local variables: | 401 | * Local variables: |
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 1e6a5632c3c7..dd00c20ab95e 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h | |||
@@ -73,6 +73,8 @@ | |||
73 | 73 | ||
74 | #define UNSET (-1U) | 74 | #define UNSET (-1U) |
75 | 75 | ||
76 | #define clamp(x, low, high) min (max (low, x), high) | ||
77 | |||
76 | /* ---------------------------------------------------------- */ | 78 | /* ---------------------------------------------------------- */ |
77 | 79 | ||
78 | struct bttv_tvnorm { | 80 | struct bttv_tvnorm { |
@@ -88,6 +90,9 @@ struct bttv_tvnorm { | |||
88 | u8 vbipack; | 90 | u8 vbipack; |
89 | u16 vtotal; | 91 | u16 vtotal; |
90 | int sram; | 92 | int sram; |
93 | /* ITU-R frame line number of the first VBI line we can | ||
94 | capture, of the first and second field. */ | ||
95 | u16 vbistart[2]; | ||
91 | }; | 96 | }; |
92 | extern const struct bttv_tvnorm bttv_tvnorms[]; | 97 | extern const struct bttv_tvnorm bttv_tvnorms[]; |
93 | 98 | ||
@@ -209,7 +214,6 @@ extern struct bus_type bttv_sub_bus_type; | |||
209 | int bttv_sub_add_device(struct bttv_core *core, char *name); | 214 | int bttv_sub_add_device(struct bttv_core *core, char *name); |
210 | int bttv_sub_del_devices(struct bttv_core *core); | 215 | int bttv_sub_del_devices(struct bttv_core *core); |
211 | void bttv_gpio_irq(struct bttv_core *core); | 216 | void bttv_gpio_irq(struct bttv_core *core); |
212 | int bttv_any_irq(struct bttv_core *core); | ||
213 | 217 | ||
214 | 218 | ||
215 | /* ---------------------------------------------------------- */ | 219 | /* ---------------------------------------------------------- */ |
@@ -270,12 +274,13 @@ struct bttv { | |||
270 | /* card configuration info */ | 274 | /* card configuration info */ |
271 | unsigned int cardid; /* pci subsystem id (bt878 based ones) */ | 275 | unsigned int cardid; /* pci subsystem id (bt878 based ones) */ |
272 | unsigned int tuner_type; /* tuner chip type */ | 276 | unsigned int tuner_type; /* tuner chip type */ |
273 | unsigned int pinnacle_id; | 277 | unsigned int tda9887_conf; |
274 | unsigned int svhs; | 278 | unsigned int svhs; |
275 | struct bttv_pll_info pll; | 279 | struct bttv_pll_info pll; |
276 | int triton1; | 280 | int triton1; |
277 | int gpioirq; | 281 | int gpioirq; |
278 | int any_irq; | 282 | int (*custom_irq)(struct bttv *btv); |
283 | |||
279 | int use_i2c_hw; | 284 | int use_i2c_hw; |
280 | 285 | ||
281 | /* old gpio interface */ | 286 | /* old gpio interface */ |
@@ -300,7 +305,7 @@ struct bttv { | |||
300 | 305 | ||
301 | /* infrared remote */ | 306 | /* infrared remote */ |
302 | int has_remote; | 307 | int has_remote; |
303 | struct bttv_input *remote; | 308 | struct bttv_ir *remote; |
304 | 309 | ||
305 | /* locking */ | 310 | /* locking */ |
306 | spinlock_t s_lock; | 311 | spinlock_t s_lock; |
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 0065d0c240d1..6bad93ef969f 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
@@ -875,6 +875,7 @@ static struct file_operations qcam_fops = { | |||
875 | .open = video_exclusive_open, | 875 | .open = video_exclusive_open, |
876 | .release = video_exclusive_release, | 876 | .release = video_exclusive_release, |
877 | .ioctl = qcam_ioctl, | 877 | .ioctl = qcam_ioctl, |
878 | .compat_ioctl = v4l_compat_ioctl32, | ||
878 | .read = qcam_read, | 879 | .read = qcam_read, |
879 | .llseek = no_llseek, | 880 | .llseek = no_llseek, |
880 | }; | 881 | }; |
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 75442ec49f35..9976db4f6da8 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
@@ -687,6 +687,7 @@ static struct file_operations qcam_fops = { | |||
687 | .open = video_exclusive_open, | 687 | .open = video_exclusive_open, |
688 | .release = video_exclusive_release, | 688 | .release = video_exclusive_release, |
689 | .ioctl = qcam_ioctl, | 689 | .ioctl = qcam_ioctl, |
690 | .compat_ioctl = v4l_compat_ioctl32, | ||
690 | .read = qcam_read, | 691 | .read = qcam_read, |
691 | .llseek = no_llseek, | 692 | .llseek = no_llseek, |
692 | }; | 693 | }; |
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c new file mode 100644 index 000000000000..6194b0125576 --- /dev/null +++ b/drivers/media/video/compat_ioctl32.c | |||
@@ -0,0 +1,732 @@ | |||
1 | /* | ||
2 | * ioctl32.c: Conversion between 32bit and 64bit native ioctls. | ||
3 | * Separated from fs stuff by Arnd Bergmann <arnd@arndb.de> | ||
4 | * | ||
5 | * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) | ||
6 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | ||
7 | * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs | ||
8 | * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) | ||
9 | * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be) | ||
10 | * | ||
11 | * These routines maintain argument size conversion between 32bit and 64bit | ||
12 | * ioctls. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/compat.h> | ||
17 | #include <linux/videodev.h> | ||
18 | #include <linux/videodev2.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/smp_lock.h> | ||
21 | |||
22 | #ifdef CONFIG_COMPAT | ||
23 | struct video_tuner32 { | ||
24 | compat_int_t tuner; | ||
25 | char name[32]; | ||
26 | compat_ulong_t rangelow, rangehigh; | ||
27 | u32 flags; /* It is really u32 in videodev.h */ | ||
28 | u16 mode, signal; | ||
29 | }; | ||
30 | |||
31 | static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | ||
32 | { | ||
33 | if(get_user(kp->tuner, &up->tuner)) | ||
34 | return -EFAULT; | ||
35 | __copy_from_user(kp->name, up->name, 32); | ||
36 | __get_user(kp->rangelow, &up->rangelow); | ||
37 | __get_user(kp->rangehigh, &up->rangehigh); | ||
38 | __get_user(kp->flags, &up->flags); | ||
39 | __get_user(kp->mode, &up->mode); | ||
40 | __get_user(kp->signal, &up->signal); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | ||
45 | { | ||
46 | if(put_user(kp->tuner, &up->tuner)) | ||
47 | return -EFAULT; | ||
48 | __copy_to_user(up->name, kp->name, 32); | ||
49 | __put_user(kp->rangelow, &up->rangelow); | ||
50 | __put_user(kp->rangehigh, &up->rangehigh); | ||
51 | __put_user(kp->flags, &up->flags); | ||
52 | __put_user(kp->mode, &up->mode); | ||
53 | __put_user(kp->signal, &up->signal); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | struct video_buffer32 { | ||
58 | compat_caddr_t base; | ||
59 | compat_int_t height, width, depth, bytesperline; | ||
60 | }; | ||
61 | |||
62 | static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) | ||
63 | { | ||
64 | u32 tmp; | ||
65 | |||
66 | if (get_user(tmp, &up->base)) | ||
67 | return -EFAULT; | ||
68 | |||
69 | /* This is actually a physical address stored | ||
70 | * as a void pointer. | ||
71 | */ | ||
72 | kp->base = (void *)(unsigned long) tmp; | ||
73 | |||
74 | __get_user(kp->height, &up->height); | ||
75 | __get_user(kp->width, &up->width); | ||
76 | __get_user(kp->depth, &up->depth); | ||
77 | __get_user(kp->bytesperline, &up->bytesperline); | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) | ||
82 | { | ||
83 | u32 tmp = (u32)((unsigned long)kp->base); | ||
84 | |||
85 | if(put_user(tmp, &up->base)) | ||
86 | return -EFAULT; | ||
87 | __put_user(kp->height, &up->height); | ||
88 | __put_user(kp->width, &up->width); | ||
89 | __put_user(kp->depth, &up->depth); | ||
90 | __put_user(kp->bytesperline, &up->bytesperline); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | struct video_clip32 { | ||
95 | s32 x, y, width, height; /* Its really s32 in videodev.h */ | ||
96 | compat_caddr_t next; | ||
97 | }; | ||
98 | |||
99 | struct video_window32 { | ||
100 | u32 x, y, width, height, chromakey, flags; | ||
101 | compat_caddr_t clips; | ||
102 | compat_int_t clipcount; | ||
103 | }; | ||
104 | |||
105 | static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
106 | { | ||
107 | int ret = -ENOIOCTLCMD; | ||
108 | |||
109 | if (file->f_op->unlocked_ioctl) | ||
110 | ret = file->f_op->unlocked_ioctl(file, cmd, arg); | ||
111 | else if (file->f_op->ioctl) { | ||
112 | lock_kernel(); | ||
113 | ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg); | ||
114 | unlock_kernel(); | ||
115 | } | ||
116 | |||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | |||
121 | /* You get back everything except the clips... */ | ||
122 | static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) | ||
123 | { | ||
124 | if(put_user(kp->x, &up->x)) | ||
125 | return -EFAULT; | ||
126 | __put_user(kp->y, &up->y); | ||
127 | __put_user(kp->width, &up->width); | ||
128 | __put_user(kp->height, &up->height); | ||
129 | __put_user(kp->chromakey, &up->chromakey); | ||
130 | __put_user(kp->flags, &up->flags); | ||
131 | __put_user(kp->clipcount, &up->clipcount); | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | struct v4l2_clip32 | ||
136 | { | ||
137 | struct v4l2_rect c; | ||
138 | compat_caddr_t next; | ||
139 | }; | ||
140 | |||
141 | struct v4l2_window32 | ||
142 | { | ||
143 | struct v4l2_rect w; | ||
144 | enum v4l2_field field; | ||
145 | __u32 chromakey; | ||
146 | compat_caddr_t clips; /* actually struct v4l2_clip32 * */ | ||
147 | __u32 clipcount; | ||
148 | compat_caddr_t bitmap; | ||
149 | }; | ||
150 | |||
151 | static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | ||
152 | { | ||
153 | if (copy_from_user(&kp->w, &up->w, sizeof(up->w))) | ||
154 | return -EFAULT; | ||
155 | __get_user(kp->field, &up->field); | ||
156 | __get_user(kp->chromakey, &up->chromakey); | ||
157 | __get_user(kp->clipcount, &up->clipcount); | ||
158 | if (kp->clipcount > 2048) | ||
159 | return -EINVAL; | ||
160 | if (kp->clipcount) { | ||
161 | struct v4l2_clip32 *uclips = compat_ptr(up->clips); | ||
162 | struct v4l2_clip *kclips; | ||
163 | int n = kp->clipcount; | ||
164 | |||
165 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); | ||
166 | kp->clips = kclips; | ||
167 | while (--n >= 0) { | ||
168 | copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)); | ||
169 | kclips->next = n ? kclips + 1 : 0; | ||
170 | uclips += 1; | ||
171 | kclips += 1; | ||
172 | } | ||
173 | } else | ||
174 | kp->clips = 0; | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | ||
179 | { | ||
180 | if (copy_to_user(&up->w, &kp->w, sizeof(up->w))) | ||
181 | return -EFAULT; | ||
182 | __put_user(kp->field, &up->field); | ||
183 | __put_user(kp->chromakey, &up->chromakey); | ||
184 | __put_user(kp->clipcount, &up->clipcount); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | ||
189 | { | ||
190 | return copy_from_user(kp, up, sizeof(struct v4l2_pix_format)); | ||
191 | } | ||
192 | |||
193 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | ||
194 | { | ||
195 | return copy_to_user(up, kp, sizeof(struct v4l2_pix_format)); | ||
196 | } | ||
197 | |||
198 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | ||
199 | { | ||
200 | return copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)); | ||
201 | } | ||
202 | |||
203 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | ||
204 | { | ||
205 | return copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)); | ||
206 | } | ||
207 | |||
208 | struct v4l2_format32 | ||
209 | { | ||
210 | enum v4l2_buf_type type; | ||
211 | union | ||
212 | { | ||
213 | struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
214 | struct v4l2_window32 win; // V4L2_BUF_TYPE_VIDEO_OVERLAY | ||
215 | struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE | ||
216 | __u8 raw_data[200]; // user-defined | ||
217 | } fmt; | ||
218 | }; | ||
219 | |||
220 | static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) | ||
221 | { | ||
222 | if(get_user(kp->type, &up->type)) | ||
223 | return -EFAULT; | ||
224 | switch (kp->type) { | ||
225 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
226 | return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); | ||
227 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
228 | return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); | ||
229 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
230 | return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); | ||
231 | default: | ||
232 | printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n", | ||
233 | kp->type); | ||
234 | return -ENXIO; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) | ||
239 | { | ||
240 | if(put_user(kp->type, &up->type)) | ||
241 | return -EFAULT; | ||
242 | switch (kp->type) { | ||
243 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
244 | return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); | ||
245 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
246 | return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); | ||
247 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
248 | return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); | ||
249 | default: | ||
250 | return -ENXIO; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | struct v4l2_standard32 | ||
255 | { | ||
256 | __u32 index; | ||
257 | __u32 id[2]; /* __u64 would get the alignment wrong */ | ||
258 | __u8 name[24]; | ||
259 | struct v4l2_fract frameperiod; /* Frames, not fields */ | ||
260 | __u32 framelines; | ||
261 | __u32 reserved[4]; | ||
262 | }; | ||
263 | |||
264 | static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) | ||
265 | { | ||
266 | /* other fields are not set by the user, nor used by the driver */ | ||
267 | return get_user(kp->index, &up->index); | ||
268 | } | ||
269 | |||
270 | static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) | ||
271 | { | ||
272 | if(put_user(kp->index, &up->index)) | ||
273 | return -EFAULT; | ||
274 | __copy_to_user(up->id, &kp->id, sizeof(__u64)); | ||
275 | __copy_to_user(up->name, kp->name, 24); | ||
276 | __put_user(kp->frameperiod, &up->frameperiod); | ||
277 | __put_user(kp->framelines, &up->framelines); | ||
278 | __copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)); | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | struct v4l2_buffer32 | ||
283 | { | ||
284 | __u32 index; | ||
285 | enum v4l2_buf_type type; | ||
286 | __u32 bytesused; | ||
287 | __u32 flags; | ||
288 | enum v4l2_field field; | ||
289 | struct compat_timeval timestamp; | ||
290 | struct v4l2_timecode timecode; | ||
291 | __u32 sequence; | ||
292 | |||
293 | /* memory location */ | ||
294 | enum v4l2_memory memory; | ||
295 | union { | ||
296 | __u32 offset; | ||
297 | compat_long_t userptr; | ||
298 | } m; | ||
299 | __u32 length; | ||
300 | __u32 input; | ||
301 | __u32 reserved; | ||
302 | }; | ||
303 | |||
304 | static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) | ||
305 | { | ||
306 | |||
307 | if (get_user(kp->index, &up->index)) | ||
308 | return -EFAULT; | ||
309 | __get_user(kp->type, &up->type); | ||
310 | __get_user(kp->flags, &up->flags); | ||
311 | __get_user(kp->memory, &up->memory); | ||
312 | __get_user(kp->input, &up->input); | ||
313 | switch(kp->memory) { | ||
314 | case V4L2_MEMORY_MMAP: | ||
315 | break; | ||
316 | case V4L2_MEMORY_USERPTR: | ||
317 | { | ||
318 | unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); | ||
319 | |||
320 | __get_user(kp->length, &up->length); | ||
321 | __get_user(kp->m.userptr, &tmp); | ||
322 | } | ||
323 | break; | ||
324 | case V4L2_MEMORY_OVERLAY: | ||
325 | __get_user(kp->m.offset, &up->m.offset); | ||
326 | break; | ||
327 | } | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) | ||
332 | { | ||
333 | if (put_user(kp->index, &up->index)) | ||
334 | return -EFAULT; | ||
335 | __put_user(kp->type, &up->type); | ||
336 | __put_user(kp->flags, &up->flags); | ||
337 | __put_user(kp->memory, &up->memory); | ||
338 | __put_user(kp->input, &up->input); | ||
339 | switch(kp->memory) { | ||
340 | case V4L2_MEMORY_MMAP: | ||
341 | __put_user(kp->length, &up->length); | ||
342 | __put_user(kp->m.offset, &up->m.offset); | ||
343 | break; | ||
344 | case V4L2_MEMORY_USERPTR: | ||
345 | __put_user(kp->length, &up->length); | ||
346 | __put_user(kp->m.userptr, &up->m.userptr); | ||
347 | break; | ||
348 | case V4L2_MEMORY_OVERLAY: | ||
349 | __put_user(kp->m.offset, &up->m.offset); | ||
350 | break; | ||
351 | } | ||
352 | __put_user(kp->bytesused, &up->bytesused); | ||
353 | __put_user(kp->field, &up->field); | ||
354 | __put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec); | ||
355 | __put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec); | ||
356 | __copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)); | ||
357 | __put_user(kp->sequence, &up->sequence); | ||
358 | __put_user(kp->reserved, &up->reserved); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | struct v4l2_framebuffer32 | ||
363 | { | ||
364 | __u32 capability; | ||
365 | __u32 flags; | ||
366 | compat_caddr_t base; | ||
367 | struct v4l2_pix_format fmt; | ||
368 | }; | ||
369 | |||
370 | static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) | ||
371 | { | ||
372 | u32 tmp; | ||
373 | |||
374 | if (get_user(tmp, &up->base)) | ||
375 | return -EFAULT; | ||
376 | kp->base = compat_ptr(tmp); | ||
377 | __get_user(kp->capability, &up->capability); | ||
378 | __get_user(kp->flags, &up->flags); | ||
379 | get_v4l2_pix_format(&kp->fmt, &up->fmt); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) | ||
384 | { | ||
385 | u32 tmp = (u32)((unsigned long)kp->base); | ||
386 | |||
387 | if(put_user(tmp, &up->base)) | ||
388 | return -EFAULT; | ||
389 | __put_user(kp->capability, &up->capability); | ||
390 | __put_user(kp->flags, &up->flags); | ||
391 | put_v4l2_pix_format(&kp->fmt, &up->fmt); | ||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | struct v4l2_input32 /* identical layout, but different size */ | ||
396 | { | ||
397 | __u32 index; /* Which input */ | ||
398 | __u8 name[32]; /* Label */ | ||
399 | __u32 type; /* Type of input */ | ||
400 | __u32 audioset; /* Associated audios (bitfield) */ | ||
401 | __u32 tuner; /* Associated tuner */ | ||
402 | __u32 std[2]; /* __u64 would get the padding wrong */ | ||
403 | __u32 status; | ||
404 | __u32 reserved[4]; | ||
405 | }; | ||
406 | |||
407 | #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) | ||
408 | #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) | ||
409 | #define VIDIOCGWIN32 _IOR('v',9, struct video_window32) | ||
410 | #define VIDIOCSWIN32 _IOW('v',10, struct video_window32) | ||
411 | #define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) | ||
412 | #define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) | ||
413 | #define VIDIOCGFREQ32 _IOR('v',14, u32) | ||
414 | #define VIDIOCSFREQ32 _IOW('v',15, u32) | ||
415 | |||
416 | #define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32) | ||
417 | #define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32) | ||
418 | #define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32) | ||
419 | #define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) | ||
420 | #define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32) | ||
421 | /* VIDIOC_OVERLAY is now _IOW, but was _IOWR */ | ||
422 | #define VIDIOC_OVERLAY32 _IOWR ('V', 14, compat_int_t) | ||
423 | #define VIDIOC_QBUF32 _IOWR ('V', 15, struct v4l2_buffer32) | ||
424 | #define VIDIOC_DQBUF32 _IOWR ('V', 17, struct v4l2_buffer32) | ||
425 | #define VIDIOC_STREAMON32 _IOW ('V', 18, compat_int_t) | ||
426 | #define VIDIOC_STREAMOFF32 _IOW ('V', 19, compat_int_t) | ||
427 | #define VIDIOC_ENUMSTD32 _IOWR ('V', 25, struct v4l2_standard32) | ||
428 | #define VIDIOC_ENUMINPUT32 _IOWR ('V', 26, struct v4l2_input32) | ||
429 | /* VIDIOC_S_CTRL is now _IOWR, but was _IOW */ | ||
430 | #define VIDIOC_S_CTRL32 _IOW ('V', 28, struct v4l2_control) | ||
431 | #define VIDIOC_G_INPUT32 _IOR ('V', 38, compat_int_t) | ||
432 | #define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t) | ||
433 | #define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32) | ||
434 | |||
435 | enum { | ||
436 | MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) | ||
437 | }; | ||
438 | |||
439 | static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg) | ||
440 | { | ||
441 | struct video_window32 __user *up = compat_ptr(arg); | ||
442 | struct video_window __user *vw; | ||
443 | struct video_clip __user *p; | ||
444 | int nclips; | ||
445 | u32 n; | ||
446 | |||
447 | if (get_user(nclips, &up->clipcount)) | ||
448 | return -EFAULT; | ||
449 | |||
450 | /* Peculiar interface... */ | ||
451 | if (nclips < 0) | ||
452 | nclips = VIDEO_CLIPMAP_SIZE; | ||
453 | |||
454 | if (nclips > MaxClips) | ||
455 | return -ENOMEM; | ||
456 | |||
457 | vw = compat_alloc_user_space(sizeof(struct video_window) + | ||
458 | nclips * sizeof(struct video_clip)); | ||
459 | |||
460 | p = nclips ? (struct video_clip __user *)(vw + 1) : NULL; | ||
461 | |||
462 | if (get_user(n, &up->x) || put_user(n, &vw->x) || | ||
463 | get_user(n, &up->y) || put_user(n, &vw->y) || | ||
464 | get_user(n, &up->width) || put_user(n, &vw->width) || | ||
465 | get_user(n, &up->height) || put_user(n, &vw->height) || | ||
466 | get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) || | ||
467 | get_user(n, &up->flags) || put_user(n, &vw->flags) || | ||
468 | get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) || | ||
469 | get_user(n, &up->clips) || put_user(p, &vw->clips)) | ||
470 | return -EFAULT; | ||
471 | |||
472 | if (nclips) { | ||
473 | struct video_clip32 __user *u = compat_ptr(n); | ||
474 | int i; | ||
475 | if (!u) | ||
476 | return -EINVAL; | ||
477 | for (i = 0; i < nclips; i++, u++, p++) { | ||
478 | s32 v; | ||
479 | if (get_user(v, &u->x) || | ||
480 | put_user(v, &p->x) || | ||
481 | get_user(v, &u->y) || | ||
482 | put_user(v, &p->y) || | ||
483 | get_user(v, &u->width) || | ||
484 | put_user(v, &p->width) || | ||
485 | get_user(v, &u->height) || | ||
486 | put_user(v, &p->height) || | ||
487 | put_user(NULL, &p->next)) | ||
488 | return -EFAULT; | ||
489 | } | ||
490 | } | ||
491 | |||
492 | return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw); | ||
493 | } | ||
494 | |||
495 | static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
496 | { | ||
497 | union { | ||
498 | struct video_tuner vt; | ||
499 | struct video_buffer vb; | ||
500 | struct video_window vw; | ||
501 | struct v4l2_format v2f; | ||
502 | struct v4l2_buffer v2b; | ||
503 | struct v4l2_framebuffer v2fb; | ||
504 | struct v4l2_standard v2s; | ||
505 | unsigned long vx; | ||
506 | } karg; | ||
507 | void __user *up = compat_ptr(arg); | ||
508 | int compatible_arg = 1; | ||
509 | int err = 0; | ||
510 | |||
511 | /* First, convert the command. */ | ||
512 | switch(cmd) { | ||
513 | case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; | ||
514 | case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; | ||
515 | case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; | ||
516 | case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; | ||
517 | case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; | ||
518 | case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; | ||
519 | case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; | ||
520 | case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; | ||
521 | case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; | ||
522 | case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; | ||
523 | case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break; | ||
524 | case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break; | ||
525 | case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; | ||
526 | case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; | ||
527 | case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break; | ||
528 | case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break; | ||
529 | case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; | ||
530 | case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break; | ||
531 | case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break; | ||
532 | case VIDIOC_S_CTRL32: cmd = VIDIOC_S_CTRL; break; | ||
533 | case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; | ||
534 | case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; | ||
535 | case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; | ||
536 | }; | ||
537 | |||
538 | switch(cmd) { | ||
539 | case VIDIOCSTUNER: | ||
540 | case VIDIOCGTUNER: | ||
541 | err = get_video_tuner32(&karg.vt, up); | ||
542 | compatible_arg = 0; | ||
543 | |||
544 | break; | ||
545 | |||
546 | case VIDIOCSFBUF: | ||
547 | err = get_video_buffer32(&karg.vb, up); | ||
548 | compatible_arg = 0; | ||
549 | break; | ||
550 | |||
551 | case VIDIOCSFREQ: | ||
552 | case VIDIOC_S_INPUT: | ||
553 | case VIDIOC_OVERLAY: | ||
554 | case VIDIOC_STREAMON: | ||
555 | case VIDIOC_STREAMOFF: | ||
556 | err = get_user(karg.vx, (u32 __user *)up); | ||
557 | compatible_arg = 0; | ||
558 | break; | ||
559 | |||
560 | case VIDIOC_S_FBUF: | ||
561 | err = get_v4l2_framebuffer32(&karg.v2fb, up); | ||
562 | compatible_arg = 0; | ||
563 | break; | ||
564 | |||
565 | case VIDIOC_G_FMT: | ||
566 | case VIDIOC_S_FMT: | ||
567 | case VIDIOC_TRY_FMT: | ||
568 | err = get_v4l2_format32(&karg.v2f, up); | ||
569 | compatible_arg = 0; | ||
570 | break; | ||
571 | |||
572 | case VIDIOC_QUERYBUF: | ||
573 | case VIDIOC_QBUF: | ||
574 | case VIDIOC_DQBUF: | ||
575 | err = get_v4l2_buffer32(&karg.v2b, up); | ||
576 | compatible_arg = 0; | ||
577 | break; | ||
578 | |||
579 | case VIDIOC_ENUMSTD: | ||
580 | err = get_v4l2_standard32(&karg.v2s, up); | ||
581 | compatible_arg = 0; | ||
582 | break; | ||
583 | |||
584 | case VIDIOCGWIN: | ||
585 | case VIDIOCGFBUF: | ||
586 | case VIDIOCGFREQ: | ||
587 | case VIDIOC_G_FBUF: | ||
588 | case VIDIOC_G_INPUT: | ||
589 | compatible_arg = 0; | ||
590 | }; | ||
591 | |||
592 | if(err) | ||
593 | goto out; | ||
594 | |||
595 | if(compatible_arg) | ||
596 | err = native_ioctl(file, cmd, (unsigned long)up); | ||
597 | else { | ||
598 | mm_segment_t old_fs = get_fs(); | ||
599 | |||
600 | set_fs(KERNEL_DS); | ||
601 | err = native_ioctl(file, cmd, (unsigned long)&karg); | ||
602 | set_fs(old_fs); | ||
603 | } | ||
604 | if(err == 0) { | ||
605 | switch(cmd) { | ||
606 | case VIDIOCGTUNER: | ||
607 | err = put_video_tuner32(&karg.vt, up); | ||
608 | break; | ||
609 | |||
610 | case VIDIOCGWIN: | ||
611 | err = put_video_window32(&karg.vw, up); | ||
612 | break; | ||
613 | |||
614 | case VIDIOCGFBUF: | ||
615 | err = put_video_buffer32(&karg.vb, up); | ||
616 | break; | ||
617 | |||
618 | case VIDIOC_G_FBUF: | ||
619 | err = put_v4l2_framebuffer32(&karg.v2fb, up); | ||
620 | break; | ||
621 | |||
622 | case VIDIOC_G_FMT: | ||
623 | case VIDIOC_S_FMT: | ||
624 | case VIDIOC_TRY_FMT: | ||
625 | err = put_v4l2_format32(&karg.v2f, up); | ||
626 | break; | ||
627 | |||
628 | case VIDIOC_QUERYBUF: | ||
629 | case VIDIOC_QBUF: | ||
630 | case VIDIOC_DQBUF: | ||
631 | err = put_v4l2_buffer32(&karg.v2b, up); | ||
632 | break; | ||
633 | |||
634 | case VIDIOC_ENUMSTD: | ||
635 | err = put_v4l2_standard32(&karg.v2s, up); | ||
636 | break; | ||
637 | |||
638 | case VIDIOCGFREQ: | ||
639 | case VIDIOC_G_INPUT: | ||
640 | err = put_user(((u32)karg.vx), (u32 __user *)up); | ||
641 | break; | ||
642 | }; | ||
643 | } | ||
644 | out: | ||
645 | return err; | ||
646 | } | ||
647 | |||
648 | long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | ||
649 | { | ||
650 | int ret = -ENOIOCTLCMD; | ||
651 | |||
652 | if (!file->f_op->ioctl) | ||
653 | return ret; | ||
654 | |||
655 | switch (cmd) { | ||
656 | case VIDIOCSWIN32: | ||
657 | ret = do_set_window(file, cmd, arg); | ||
658 | break; | ||
659 | case VIDIOCGTUNER32: | ||
660 | case VIDIOCSTUNER32: | ||
661 | case VIDIOCGWIN32: | ||
662 | case VIDIOCGFBUF32: | ||
663 | case VIDIOCSFBUF32: | ||
664 | case VIDIOCGFREQ32: | ||
665 | case VIDIOCSFREQ32: | ||
666 | case VIDIOC_QUERYCAP: | ||
667 | case VIDIOC_ENUM_FMT: | ||
668 | case VIDIOC_G_FMT32: | ||
669 | case VIDIOC_S_FMT32: | ||
670 | case VIDIOC_REQBUFS: | ||
671 | case VIDIOC_QUERYBUF32: | ||
672 | case VIDIOC_G_FBUF32: | ||
673 | case VIDIOC_S_FBUF32: | ||
674 | case VIDIOC_OVERLAY32: | ||
675 | case VIDIOC_QBUF32: | ||
676 | case VIDIOC_DQBUF32: | ||
677 | case VIDIOC_STREAMON32: | ||
678 | case VIDIOC_STREAMOFF32: | ||
679 | case VIDIOC_G_PARM: | ||
680 | case VIDIOC_G_STD: | ||
681 | case VIDIOC_S_STD: | ||
682 | case VIDIOC_ENUMSTD32: | ||
683 | case VIDIOC_ENUMINPUT32: | ||
684 | case VIDIOC_G_CTRL: | ||
685 | case VIDIOC_S_CTRL32: | ||
686 | case VIDIOC_QUERYCTRL: | ||
687 | case VIDIOC_G_INPUT32: | ||
688 | case VIDIOC_S_INPUT32: | ||
689 | case VIDIOC_TRY_FMT32: | ||
690 | ret = do_video_ioctl(file, cmd, arg); | ||
691 | break; | ||
692 | |||
693 | /* Little v, the video4linux ioctls (conflict?) */ | ||
694 | case VIDIOCGCAP: | ||
695 | case VIDIOCGCHAN: | ||
696 | case VIDIOCSCHAN: | ||
697 | case VIDIOCGPICT: | ||
698 | case VIDIOCSPICT: | ||
699 | case VIDIOCCAPTURE: | ||
700 | case VIDIOCKEY: | ||
701 | case VIDIOCGAUDIO: | ||
702 | case VIDIOCSAUDIO: | ||
703 | case VIDIOCSYNC: | ||
704 | case VIDIOCMCAPTURE: | ||
705 | case VIDIOCGMBUF: | ||
706 | case VIDIOCGUNIT: | ||
707 | case VIDIOCGCAPTURE: | ||
708 | case VIDIOCSCAPTURE: | ||
709 | |||
710 | /* BTTV specific... */ | ||
711 | case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): | ||
712 | case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): | ||
713 | case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int): | ||
714 | case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */ | ||
715 | case _IOR('v' , BASE_VIDIOCPRIVATE+4, int): | ||
716 | case _IOR('v' , BASE_VIDIOCPRIVATE+5, int): | ||
717 | case _IOR('v' , BASE_VIDIOCPRIVATE+6, int): | ||
718 | case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): | ||
719 | ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); | ||
720 | break; | ||
721 | } | ||
722 | return ret; | ||
723 | } | ||
724 | #else | ||
725 | long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | ||
726 | { | ||
727 | return -ENOIOCTLCMD; | ||
728 | } | ||
729 | #endif | ||
730 | EXPORT_SYMBOL_GPL(v4l_compat_ioctl32); | ||
731 | |||
732 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index b7ec9bf45085..9f59541155d9 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
@@ -3807,6 +3807,7 @@ static struct file_operations cpia_fops = { | |||
3807 | .read = cpia_read, | 3807 | .read = cpia_read, |
3808 | .mmap = cpia_mmap, | 3808 | .mmap = cpia_mmap, |
3809 | .ioctl = cpia_ioctl, | 3809 | .ioctl = cpia_ioctl, |
3810 | .compat_ioctl = v4l_compat_ioctl32, | ||
3810 | .llseek = no_llseek, | 3811 | .llseek = no_llseek, |
3811 | }; | 3812 | }; |
3812 | 3813 | ||
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index 643ead1a87ee..b421068f7ea3 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/i2c-id.h> | 28 | #include <linux/i2c-id.h> |
29 | #include <linux/videodev.h> | 29 | #include <linux/videodev.h> |
30 | #include <media/audiochip.h> | 30 | #include <media/v4l2-common.h> |
31 | 31 | ||
32 | MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); | 32 | MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); |
33 | MODULE_AUTHOR("Martin Vaughan"); | 33 | MODULE_AUTHOR("Martin Vaughan"); |
@@ -39,21 +39,6 @@ module_param(debug, bool, 0644); | |||
39 | 39 | ||
40 | MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); | 40 | MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); |
41 | 41 | ||
42 | #define cs53l32a_dbg(fmt, arg...) \ | ||
43 | do { \ | ||
44 | if (debug) \ | ||
45 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
46 | client->driver->driver.name, \ | ||
47 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
48 | } while (0) | ||
49 | |||
50 | #define cs53l32a_err(fmt, arg...) do { \ | ||
51 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
52 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
53 | #define cs53l32a_info(fmt, arg...) do { \ | ||
54 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
55 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
56 | |||
57 | static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; | 42 | static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; |
58 | 43 | ||
59 | 44 | ||
@@ -74,50 +59,59 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg) | |||
74 | static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, | 59 | static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, |
75 | void *arg) | 60 | void *arg) |
76 | { | 61 | { |
77 | int *input = arg; | 62 | struct v4l2_audio *input = arg; |
63 | struct v4l2_control *ctrl = arg; | ||
78 | 64 | ||
79 | switch (cmd) { | 65 | switch (cmd) { |
80 | case AUDC_SET_INPUT: | 66 | case VIDIOC_S_AUDIO: |
81 | switch (*input) { | 67 | /* There are 2 physical inputs, but the second input can be |
82 | case AUDIO_TUNER: | 68 | placed in two modes, the first mode bypasses the PGA (gain), |
83 | cs53l32a_write(client, 0x01, 0x01); | 69 | the second goes through the PGA. Hence there are three |
84 | break; | 70 | possible inputs to choose from. */ |
85 | case AUDIO_EXTERN: | 71 | if (input->index > 2) { |
86 | cs53l32a_write(client, 0x01, 0x21); | 72 | v4l_err(client, "Invalid input %d.\n", input->index); |
87 | break; | ||
88 | case AUDIO_MUTE: | ||
89 | cs53l32a_write(client, 0x03, 0xF0); | ||
90 | break; | ||
91 | case AUDIO_UNMUTE: | ||
92 | cs53l32a_write(client, 0x03, 0x30); | ||
93 | break; | ||
94 | default: | ||
95 | cs53l32a_err("Invalid input %d.\n", *input); | ||
96 | return -EINVAL; | 73 | return -EINVAL; |
97 | } | 74 | } |
75 | cs53l32a_write(client, 0x01, 0x01 + (input->index << 4)); | ||
76 | break; | ||
77 | |||
78 | case VIDIOC_G_AUDIO: | ||
79 | memset(input, 0, sizeof(*input)); | ||
80 | input->index = (cs53l32a_read(client, 0x01) >> 4) & 3; | ||
81 | break; | ||
82 | |||
83 | case VIDIOC_G_CTRL: | ||
84 | if (ctrl->id == V4L2_CID_AUDIO_MUTE) { | ||
85 | ctrl->value = (cs53l32a_read(client, 0x03) & 0xc0) != 0; | ||
86 | break; | ||
87 | } | ||
88 | if (ctrl->id != V4L2_CID_AUDIO_VOLUME) | ||
89 | return -EINVAL; | ||
90 | ctrl->value = (s8)cs53l32a_read(client, 0x04); | ||
98 | break; | 91 | break; |
99 | 92 | ||
100 | case VIDIOC_S_CTRL: | 93 | case VIDIOC_S_CTRL: |
101 | { | 94 | if (ctrl->id == V4L2_CID_AUDIO_MUTE) { |
102 | struct v4l2_control *ctrl = arg; | 95 | cs53l32a_write(client, 0x03, ctrl->value ? 0xf0 : 0x30); |
103 | |||
104 | if (ctrl->id != V4L2_CID_AUDIO_VOLUME) | ||
105 | return -EINVAL; | ||
106 | if (ctrl->value > 12 || ctrl->value < -90) | ||
107 | return -EINVAL; | ||
108 | cs53l32a_write(client, 0x04, (u8) ctrl->value); | ||
109 | cs53l32a_write(client, 0x05, (u8) ctrl->value); | ||
110 | break; | 96 | break; |
111 | } | 97 | } |
98 | if (ctrl->id != V4L2_CID_AUDIO_VOLUME) | ||
99 | return -EINVAL; | ||
100 | if (ctrl->value > 12 || ctrl->value < -96) | ||
101 | return -EINVAL; | ||
102 | cs53l32a_write(client, 0x04, (u8) ctrl->value); | ||
103 | cs53l32a_write(client, 0x05, (u8) ctrl->value); | ||
104 | break; | ||
112 | 105 | ||
113 | case VIDIOC_LOG_STATUS: | 106 | case VIDIOC_LOG_STATUS: |
114 | { | 107 | { |
115 | u8 v = cs53l32a_read(client, 0x01); | 108 | u8 v = cs53l32a_read(client, 0x01); |
116 | u8 m = cs53l32a_read(client, 0x03); | 109 | u8 m = cs53l32a_read(client, 0x03); |
110 | s8 vol = cs53l32a_read(client, 0x04); | ||
117 | 111 | ||
118 | cs53l32a_info("Input: %s%s\n", | 112 | v4l_info(client, "Input: %d%s\n", (v >> 4) & 3, |
119 | v == 0x21 ? "external line in" : "tuner", | ||
120 | (m & 0xC0) ? " (muted)" : ""); | 113 | (m & 0xC0) ? " (muted)" : ""); |
114 | v4l_info(client, "Volume: %d dB\n", vol); | ||
121 | break; | 115 | break; |
122 | } | 116 | } |
123 | 117 | ||
@@ -157,12 +151,12 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) | |||
157 | client->driver = &i2c_driver; | 151 | client->driver = &i2c_driver; |
158 | snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); | 152 | snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); |
159 | 153 | ||
160 | cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); | 154 | v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); |
161 | 155 | ||
162 | for (i = 1; i <= 7; i++) { | 156 | for (i = 1; i <= 7; i++) { |
163 | u8 v = cs53l32a_read(client, i); | 157 | u8 v = cs53l32a_read(client, i); |
164 | 158 | ||
165 | cs53l32a_dbg("Read Reg %d %02x\n", i, v); | 159 | v4l_dbg(1, client, "Read Reg %d %02x\n", i, v); |
166 | } | 160 | } |
167 | 161 | ||
168 | /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ | 162 | /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ |
@@ -180,7 +174,7 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) | |||
180 | for (i = 1; i <= 7; i++) { | 174 | for (i = 1; i <= 7; i++) { |
181 | u8 v = cs53l32a_read(client, i); | 175 | u8 v = cs53l32a_read(client, i); |
182 | 176 | ||
183 | cs53l32a_dbg("Read Reg %d %02x\n", i, v); | 177 | v4l_dbg(1, client, "Read Reg %d %02x\n", i, v); |
184 | } | 178 | } |
185 | 179 | ||
186 | i2c_attach_client(client); | 180 | i2c_attach_client(client); |
@@ -190,11 +184,7 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) | |||
190 | 184 | ||
191 | static int cs53l32a_probe(struct i2c_adapter *adapter) | 185 | static int cs53l32a_probe(struct i2c_adapter *adapter) |
192 | { | 186 | { |
193 | #ifdef I2C_CLASS_TV_ANALOG | ||
194 | if (adapter->class & I2C_CLASS_TV_ANALOG) | 187 | if (adapter->class & I2C_CLASS_TV_ANALOG) |
195 | #else | ||
196 | if (adapter->id == I2C_HW_B_BT848) | ||
197 | #endif | ||
198 | return i2c_probe(adapter, &addr_data, cs53l32a_attach); | 188 | return i2c_probe(adapter, &addr_data, cs53l32a_attach); |
199 | return 0; | 189 | return 0; |
200 | } | 190 | } |
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 740908f8027d..cb9a7981e408 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -23,11 +23,13 @@ | |||
23 | 23 | ||
24 | #include "cx25840.h" | 24 | #include "cx25840.h" |
25 | 25 | ||
26 | inline static int set_audclk_freq(struct i2c_client *client, | 26 | static int set_audclk_freq(struct i2c_client *client, u32 freq) |
27 | enum v4l2_audio_clock_freq freq) | ||
28 | { | 27 | { |
29 | struct cx25840_state *state = i2c_get_clientdata(client); | 28 | struct cx25840_state *state = i2c_get_clientdata(client); |
30 | 29 | ||
30 | if (freq != 32000 && freq != 44100 && freq != 48000) | ||
31 | return -EINVAL; | ||
32 | |||
31 | /* assert soft reset */ | 33 | /* assert soft reset */ |
32 | cx25840_and_or(client, 0x810, ~0x1, 0x01); | 34 | cx25840_and_or(client, 0x810, ~0x1, 0x01); |
33 | 35 | ||
@@ -35,10 +37,9 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
35 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | 37 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ |
36 | cx25840_write(client, 0x127, 0x50); | 38 | cx25840_write(client, 0x127, 0x50); |
37 | 39 | ||
38 | switch (state->audio_input) { | 40 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
39 | case AUDIO_TUNER: | ||
40 | switch (freq) { | 41 | switch (freq) { |
41 | case V4L2_AUDCLK_32_KHZ: | 42 | case 32000: |
42 | /* VID_PLL and AUX_PLL */ | 43 | /* VID_PLL and AUX_PLL */ |
43 | cx25840_write4(client, 0x108, 0x0f040610); | 44 | cx25840_write4(client, 0x108, 0x0f040610); |
44 | 45 | ||
@@ -51,7 +52,7 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
51 | cx25840_write4(client, 0x90c, 0x7ff70108); | 52 | cx25840_write4(client, 0x90c, 0x7ff70108); |
52 | break; | 53 | break; |
53 | 54 | ||
54 | case V4L2_AUDCLK_441_KHZ: | 55 | case 44100: |
55 | /* VID_PLL and AUX_PLL */ | 56 | /* VID_PLL and AUX_PLL */ |
56 | cx25840_write4(client, 0x108, 0x0f040910); | 57 | cx25840_write4(client, 0x108, 0x0f040910); |
57 | 58 | ||
@@ -64,7 +65,7 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
64 | cx25840_write4(client, 0x90c, 0x596d0108); | 65 | cx25840_write4(client, 0x90c, 0x596d0108); |
65 | break; | 66 | break; |
66 | 67 | ||
67 | case V4L2_AUDCLK_48_KHZ: | 68 | case 48000: |
68 | /* VID_PLL and AUX_PLL */ | 69 | /* VID_PLL and AUX_PLL */ |
69 | cx25840_write4(client, 0x108, 0x0f040a10); | 70 | cx25840_write4(client, 0x108, 0x0f040a10); |
70 | 71 | ||
@@ -77,14 +78,9 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
77 | cx25840_write4(client, 0x90c, 0xaa4f0108); | 78 | cx25840_write4(client, 0x90c, 0xaa4f0108); |
78 | break; | 79 | break; |
79 | } | 80 | } |
80 | break; | 81 | } else { |
81 | |||
82 | case AUDIO_EXTERN_1: | ||
83 | case AUDIO_EXTERN_2: | ||
84 | case AUDIO_INTERN: | ||
85 | case AUDIO_RADIO: | ||
86 | switch (freq) { | 82 | switch (freq) { |
87 | case V4L2_AUDCLK_32_KHZ: | 83 | case 32000: |
88 | /* VID_PLL and AUX_PLL */ | 84 | /* VID_PLL and AUX_PLL */ |
89 | cx25840_write4(client, 0x108, 0x0f04081e); | 85 | cx25840_write4(client, 0x108, 0x0f04081e); |
90 | 86 | ||
@@ -103,7 +99,7 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
103 | cx25840_write(client, 0x127, 0x54); | 99 | cx25840_write(client, 0x127, 0x54); |
104 | break; | 100 | break; |
105 | 101 | ||
106 | case V4L2_AUDCLK_441_KHZ: | 102 | case 44100: |
107 | /* VID_PLL and AUX_PLL */ | 103 | /* VID_PLL and AUX_PLL */ |
108 | cx25840_write4(client, 0x108, 0x0f040918); | 104 | cx25840_write4(client, 0x108, 0x0f040918); |
109 | 105 | ||
@@ -119,7 +115,7 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
119 | cx25840_write4(client, 0x90c, 0x85730108); | 115 | cx25840_write4(client, 0x90c, 0x85730108); |
120 | break; | 116 | break; |
121 | 117 | ||
122 | case V4L2_AUDCLK_48_KHZ: | 118 | case 48000: |
123 | /* VID_PLL and AUX_PLL */ | 119 | /* VID_PLL and AUX_PLL */ |
124 | cx25840_write4(client, 0x108, 0x0f040a18); | 120 | cx25840_write4(client, 0x108, 0x0f040a18); |
125 | 121 | ||
@@ -135,7 +131,6 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
135 | cx25840_write4(client, 0x90c, 0x55550108); | 131 | cx25840_write4(client, 0x90c, 0x55550108); |
136 | break; | 132 | break; |
137 | } | 133 | } |
138 | break; | ||
139 | } | 134 | } |
140 | 135 | ||
141 | /* deassert soft reset */ | 136 | /* deassert soft reset */ |
@@ -146,51 +141,36 @@ inline static int set_audclk_freq(struct i2c_client *client, | |||
146 | return 0; | 141 | return 0; |
147 | } | 142 | } |
148 | 143 | ||
149 | static int set_input(struct i2c_client *client, int audio_input) | 144 | void cx25840_audio_set_path(struct i2c_client *client) |
150 | { | 145 | { |
151 | struct cx25840_state *state = i2c_get_clientdata(client); | 146 | struct cx25840_state *state = i2c_get_clientdata(client); |
152 | 147 | ||
153 | cx25840_dbg("set audio input (%d)\n", audio_input); | ||
154 | |||
155 | /* stop microcontroller */ | 148 | /* stop microcontroller */ |
156 | cx25840_and_or(client, 0x803, ~0x10, 0); | 149 | cx25840_and_or(client, 0x803, ~0x10, 0); |
157 | 150 | ||
158 | /* Mute everything to prevent the PFFT! */ | 151 | /* Mute everything to prevent the PFFT! */ |
159 | cx25840_write(client, 0x8d3, 0x1f); | 152 | cx25840_write(client, 0x8d3, 0x1f); |
160 | 153 | ||
161 | switch (audio_input) { | 154 | if (state->aud_input == CX25840_AUDIO_SERIAL) { |
162 | case AUDIO_TUNER: | ||
163 | /* Set Path1 to Analog Demod Main Channel */ | ||
164 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
165 | |||
166 | /* When the microcontroller detects the | ||
167 | * audio format, it will unmute the lines */ | ||
168 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
169 | break; | ||
170 | |||
171 | case AUDIO_EXTERN_1: | ||
172 | case AUDIO_EXTERN_2: | ||
173 | case AUDIO_INTERN: | ||
174 | case AUDIO_RADIO: | ||
175 | /* Set Path1 to Serial Audio Input */ | 155 | /* Set Path1 to Serial Audio Input */ |
176 | cx25840_write4(client, 0x8d0, 0x12100101); | 156 | cx25840_write4(client, 0x8d0, 0x12100101); |
177 | 157 | ||
178 | /* The microcontroller should not be started for the | 158 | /* The microcontroller should not be started for the |
179 | * non-tuner inputs: autodetection is specific for | 159 | * non-tuner inputs: autodetection is specific for |
180 | * TV audio. */ | 160 | * TV audio. */ |
181 | break; | 161 | } else { |
162 | /* Set Path1 to Analog Demod Main Channel */ | ||
163 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
182 | 164 | ||
183 | default: | 165 | /* When the microcontroller detects the |
184 | cx25840_dbg("Invalid audio input selection %d\n", audio_input); | 166 | * audio format, it will unmute the lines */ |
185 | return -EINVAL; | 167 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
186 | } | 168 | } |
187 | 169 | ||
188 | state->audio_input = audio_input; | 170 | set_audclk_freq(client, state->audclk_freq); |
189 | |||
190 | return set_audclk_freq(client, state->audclk_freq); | ||
191 | } | 171 | } |
192 | 172 | ||
193 | inline static int get_volume(struct i2c_client *client) | 173 | static int get_volume(struct i2c_client *client) |
194 | { | 174 | { |
195 | /* Volume runs +18dB to -96dB in 1/2dB steps | 175 | /* Volume runs +18dB to -96dB in 1/2dB steps |
196 | * change to fit the msp3400 -114dB to +12dB range */ | 176 | * change to fit the msp3400 -114dB to +12dB range */ |
@@ -201,7 +181,7 @@ inline static int get_volume(struct i2c_client *client) | |||
201 | return vol << 9; | 181 | return vol << 9; |
202 | } | 182 | } |
203 | 183 | ||
204 | inline static void set_volume(struct i2c_client *client, int volume) | 184 | static void set_volume(struct i2c_client *client, int volume) |
205 | { | 185 | { |
206 | /* First convert the volume to msp3400 values (0-127) */ | 186 | /* First convert the volume to msp3400 values (0-127) */ |
207 | int vol = volume >> 9; | 187 | int vol = volume >> 9; |
@@ -218,7 +198,7 @@ inline static void set_volume(struct i2c_client *client, int volume) | |||
218 | cx25840_write(client, 0x8d4, 228 - (vol * 2)); | 198 | cx25840_write(client, 0x8d4, 228 - (vol * 2)); |
219 | } | 199 | } |
220 | 200 | ||
221 | inline static int get_bass(struct i2c_client *client) | 201 | static int get_bass(struct i2c_client *client) |
222 | { | 202 | { |
223 | /* bass is 49 steps +12dB to -12dB */ | 203 | /* bass is 49 steps +12dB to -12dB */ |
224 | 204 | ||
@@ -228,13 +208,13 @@ inline static int get_bass(struct i2c_client *client) | |||
228 | return bass; | 208 | return bass; |
229 | } | 209 | } |
230 | 210 | ||
231 | inline static void set_bass(struct i2c_client *client, int bass) | 211 | static void set_bass(struct i2c_client *client, int bass) |
232 | { | 212 | { |
233 | /* PATH1_EQ_BASS_VOL */ | 213 | /* PATH1_EQ_BASS_VOL */ |
234 | cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); | 214 | cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); |
235 | } | 215 | } |
236 | 216 | ||
237 | inline static int get_treble(struct i2c_client *client) | 217 | static int get_treble(struct i2c_client *client) |
238 | { | 218 | { |
239 | /* treble is 49 steps +12dB to -12dB */ | 219 | /* treble is 49 steps +12dB to -12dB */ |
240 | 220 | ||
@@ -244,13 +224,13 @@ inline static int get_treble(struct i2c_client *client) | |||
244 | return treble; | 224 | return treble; |
245 | } | 225 | } |
246 | 226 | ||
247 | inline static void set_treble(struct i2c_client *client, int treble) | 227 | static void set_treble(struct i2c_client *client, int treble) |
248 | { | 228 | { |
249 | /* PATH1_EQ_TREBLE_VOL */ | 229 | /* PATH1_EQ_TREBLE_VOL */ |
250 | cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); | 230 | cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); |
251 | } | 231 | } |
252 | 232 | ||
253 | inline static int get_balance(struct i2c_client *client) | 233 | static int get_balance(struct i2c_client *client) |
254 | { | 234 | { |
255 | /* balance is 7 bit, 0 to -96dB */ | 235 | /* balance is 7 bit, 0 to -96dB */ |
256 | 236 | ||
@@ -264,7 +244,7 @@ inline static int get_balance(struct i2c_client *client) | |||
264 | return balance << 8; | 244 | return balance << 8; |
265 | } | 245 | } |
266 | 246 | ||
267 | inline static void set_balance(struct i2c_client *client, int balance) | 247 | static void set_balance(struct i2c_client *client, int balance) |
268 | { | 248 | { |
269 | int bal = balance >> 8; | 249 | int bal = balance >> 8; |
270 | if (bal > 0x80) { | 250 | if (bal > 0x80) { |
@@ -280,17 +260,17 @@ inline static void set_balance(struct i2c_client *client, int balance) | |||
280 | } | 260 | } |
281 | } | 261 | } |
282 | 262 | ||
283 | inline static int get_mute(struct i2c_client *client) | 263 | static int get_mute(struct i2c_client *client) |
284 | { | 264 | { |
285 | /* check SRC1_MUTE_EN */ | 265 | /* check SRC1_MUTE_EN */ |
286 | return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; | 266 | return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; |
287 | } | 267 | } |
288 | 268 | ||
289 | inline static void set_mute(struct i2c_client *client, int mute) | 269 | static void set_mute(struct i2c_client *client, int mute) |
290 | { | 270 | { |
291 | struct cx25840_state *state = i2c_get_clientdata(client); | 271 | struct cx25840_state *state = i2c_get_clientdata(client); |
292 | 272 | ||
293 | if (state->audio_input == AUDIO_TUNER) { | 273 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
294 | /* Must turn off microcontroller in order to mute sound. | 274 | /* Must turn off microcontroller in order to mute sound. |
295 | * Not sure if this is the best method, but it does work. | 275 | * Not sure if this is the best method, but it does work. |
296 | * If the microcontroller is running, then it will undo any | 276 | * If the microcontroller is running, then it will undo any |
@@ -314,10 +294,9 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
314 | struct v4l2_control *ctrl = arg; | 294 | struct v4l2_control *ctrl = arg; |
315 | 295 | ||
316 | switch (cmd) { | 296 | switch (cmd) { |
317 | case AUDC_SET_INPUT: | ||
318 | return set_input(client, *(int *)arg); | ||
319 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 297 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
320 | return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg); | 298 | return set_audclk_freq(client, *(u32 *)arg); |
299 | |||
321 | case VIDIOC_G_CTRL: | 300 | case VIDIOC_G_CTRL: |
322 | switch (ctrl->id) { | 301 | switch (ctrl->id) { |
323 | case V4L2_CID_AUDIO_VOLUME: | 302 | case V4L2_CID_AUDIO_VOLUME: |
@@ -339,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
339 | return -EINVAL; | 318 | return -EINVAL; |
340 | } | 319 | } |
341 | break; | 320 | break; |
321 | |||
342 | case VIDIOC_S_CTRL: | 322 | case VIDIOC_S_CTRL: |
343 | switch (ctrl->id) { | 323 | switch (ctrl->id) { |
344 | case V4L2_CID_AUDIO_VOLUME: | 324 | case V4L2_CID_AUDIO_VOLUME: |
@@ -360,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
360 | return -EINVAL; | 340 | return -EINVAL; |
361 | } | 341 | } |
362 | break; | 342 | break; |
343 | |||
363 | default: | 344 | default: |
364 | return -EINVAL; | 345 | return -EINVAL; |
365 | } | 346 | } |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 3b09f46dddf6..d45237d508c4 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -43,11 +43,11 @@ MODULE_LICENSE("GPL"); | |||
43 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 43 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
44 | 44 | ||
45 | 45 | ||
46 | int cx25840_debug = 0; | 46 | int debug = 0; |
47 | 47 | ||
48 | module_param(cx25840_debug, bool, 0644); | 48 | module_param(debug, bool, 0644); |
49 | 49 | ||
50 | MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]"); | 50 | MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); |
51 | 51 | ||
52 | I2C_CLIENT_INSMOD; | 52 | I2C_CLIENT_INSMOD; |
53 | 53 | ||
@@ -115,13 +115,13 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, | |||
115 | 115 | ||
116 | /* ----------------------------------------------------------------------- */ | 116 | /* ----------------------------------------------------------------------- */ |
117 | 117 | ||
118 | static int set_input(struct i2c_client *, enum cx25840_input); | 118 | static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
119 | static void input_change(struct i2c_client *); | 119 | enum cx25840_audio_input aud_input); |
120 | static void log_status(struct i2c_client *client); | 120 | static void log_status(struct i2c_client *client); |
121 | 121 | ||
122 | /* ----------------------------------------------------------------------- */ | 122 | /* ----------------------------------------------------------------------- */ |
123 | 123 | ||
124 | static inline void init_dll1(struct i2c_client *client) | 124 | static void init_dll1(struct i2c_client *client) |
125 | { | 125 | { |
126 | /* This is the Hauppauge sequence used to | 126 | /* This is the Hauppauge sequence used to |
127 | * initialize the Delay Lock Loop 1 (ADC DLL). */ | 127 | * initialize the Delay Lock Loop 1 (ADC DLL). */ |
@@ -135,7 +135,7 @@ static inline void init_dll1(struct i2c_client *client) | |||
135 | cx25840_write(client, 0x15b, 0x10); | 135 | cx25840_write(client, 0x15b, 0x10); |
136 | } | 136 | } |
137 | 137 | ||
138 | static inline void init_dll2(struct i2c_client *client) | 138 | static void init_dll2(struct i2c_client *client) |
139 | { | 139 | { |
140 | /* This is the Hauppauge sequence used to | 140 | /* This is the Hauppauge sequence used to |
141 | * initialize the Delay Lock Loop 2 (ADC DLL). */ | 141 | * initialize the Delay Lock Loop 2 (ADC DLL). */ |
@@ -195,10 +195,8 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) | |||
195 | /* AC97 shift */ | 195 | /* AC97 shift */ |
196 | cx25840_write(client, 0x8cf, 0x0f); | 196 | cx25840_write(client, 0x8cf, 0x0f); |
197 | 197 | ||
198 | /* (re)set video input */ | 198 | /* (re)set input */ |
199 | set_input(client, state->input); | 199 | set_input(client, state->vid_input, state->aud_input); |
200 | /* (re)set audio input */ | ||
201 | cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input); | ||
202 | 200 | ||
203 | /* start microcontroller */ | 201 | /* start microcontroller */ |
204 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 202 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
@@ -223,7 +221,7 @@ static void input_change(struct i2c_client *client) | |||
223 | cx25840_write(client, 0x80b, 0x10); | 221 | cx25840_write(client, 0x80b, 0x10); |
224 | } else if (std & V4L2_STD_NTSC) { | 222 | } else if (std & V4L2_STD_NTSC) { |
225 | /* NTSC */ | 223 | /* NTSC */ |
226 | if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { | 224 | if (state->pvr150_workaround) { |
227 | /* Certain Hauppauge PVR150 models have a hardware bug | 225 | /* Certain Hauppauge PVR150 models have a hardware bug |
228 | that causes audio to drop out. For these models the | 226 | that causes audio to drop out. For these models the |
229 | audio standard must be set explicitly. | 227 | audio standard must be set explicitly. |
@@ -259,72 +257,68 @@ static void input_change(struct i2c_client *client) | |||
259 | } | 257 | } |
260 | } | 258 | } |
261 | 259 | ||
262 | static int set_input(struct i2c_client *client, enum cx25840_input input) | 260 | static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
261 | enum cx25840_audio_input aud_input) | ||
263 | { | 262 | { |
264 | struct cx25840_state *state = i2c_get_clientdata(client); | 263 | struct cx25840_state *state = i2c_get_clientdata(client); |
264 | u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && | ||
265 | vid_input <= CX25840_COMPOSITE8); | ||
266 | u8 reg; | ||
265 | 267 | ||
266 | cx25840_dbg("decoder set input (%d)\n", input); | 268 | v4l_dbg(1, client, "decoder set video input %d, audio input %d\n", |
269 | vid_input, aud_input); | ||
267 | 270 | ||
268 | switch (input) { | 271 | if (is_composite) { |
269 | case CX25840_TUNER: | 272 | reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); |
270 | cx25840_dbg("now setting Tuner input\n"); | 273 | } else { |
271 | 274 | int luma = vid_input & 0xf0; | |
272 | if (state->cardtype == CARDTYPE_PVR150 || | 275 | int chroma = vid_input & 0xf00; |
273 | state->cardtype == CARDTYPE_PVR150_WORKAROUND) { | ||
274 | /* CH_SEL_ADC2=1 */ | ||
275 | cx25840_and_or(client, 0x102, ~0x2, 0x02); | ||
276 | } | ||
277 | |||
278 | /* Video Input Control */ | ||
279 | if (state->cardtype == CARDTYPE_PG600) { | ||
280 | cx25840_write(client, 0x103, 0x11); | ||
281 | } else { | ||
282 | cx25840_write(client, 0x103, 0x46); | ||
283 | } | ||
284 | |||
285 | /* INPUT_MODE=0 */ | ||
286 | cx25840_and_or(client, 0x401, ~0x6, 0x00); | ||
287 | break; | ||
288 | |||
289 | case CX25840_COMPOSITE0: | ||
290 | case CX25840_COMPOSITE1: | ||
291 | cx25840_dbg("now setting Composite input\n"); | ||
292 | 276 | ||
293 | /* Video Input Control */ | 277 | if ((vid_input & ~0xff0) || |
294 | if (state->cardtype == CARDTYPE_PG600) { | 278 | luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 || |
295 | cx25840_write(client, 0x103, 0x00); | 279 | chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { |
296 | } else { | 280 | v4l_err(client, "0x%04x is not a valid video input!\n", vid_input); |
297 | cx25840_write(client, 0x103, 0x02); | 281 | return -EINVAL; |
298 | } | 282 | } |
299 | 283 | reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4); | |
300 | /* INPUT_MODE=0 */ | 284 | if (chroma >= CX25840_SVIDEO_CHROMA7) { |
301 | cx25840_and_or(client, 0x401, ~0x6, 0x00); | 285 | reg &= 0x3f; |
302 | break; | 286 | reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2; |
303 | |||
304 | case CX25840_SVIDEO0: | ||
305 | case CX25840_SVIDEO1: | ||
306 | cx25840_dbg("now setting S-Video input\n"); | ||
307 | |||
308 | /* CH_SEL_ADC2=0 */ | ||
309 | cx25840_and_or(client, 0x102, ~0x2, 0x00); | ||
310 | |||
311 | /* Video Input Control */ | ||
312 | if (state->cardtype == CARDTYPE_PG600) { | ||
313 | cx25840_write(client, 0x103, 0x02); | ||
314 | } else { | 287 | } else { |
315 | cx25840_write(client, 0x103, 0x10); | 288 | reg &= 0xcf; |
289 | reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4; | ||
316 | } | 290 | } |
291 | } | ||
317 | 292 | ||
318 | /* INPUT_MODE=1 */ | 293 | switch (aud_input) { |
319 | cx25840_and_or(client, 0x401, ~0x6, 0x02); | 294 | case CX25840_AUDIO_SERIAL: |
295 | /* do nothing, use serial audio input */ | ||
320 | break; | 296 | break; |
297 | case CX25840_AUDIO4: reg &= ~0x30; break; | ||
298 | case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break; | ||
299 | case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break; | ||
300 | case CX25840_AUDIO7: reg &= ~0xc0; break; | ||
301 | case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; | ||
321 | 302 | ||
322 | default: | 303 | default: |
323 | cx25840_err("%d is not a valid input!\n", input); | 304 | v4l_err(client, "0x%04x is not a valid audio input!\n", aud_input); |
324 | return -EINVAL; | 305 | return -EINVAL; |
325 | } | 306 | } |
326 | 307 | ||
327 | state->input = input; | 308 | cx25840_write(client, 0x103, reg); |
309 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ | ||
310 | cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); | ||
311 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ | ||
312 | cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); | ||
313 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ | ||
314 | if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) | ||
315 | cx25840_and_or(client, 0x102, ~0x4, 4); | ||
316 | else | ||
317 | cx25840_and_or(client, 0x102, ~0x4, 0); | ||
318 | |||
319 | state->vid_input = vid_input; | ||
320 | state->aud_input = aud_input; | ||
321 | cx25840_audio_set_path(client); | ||
328 | input_change(client); | 322 | input_change(client); |
329 | return 0; | 323 | return 0; |
330 | } | 324 | } |
@@ -395,23 +389,14 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
395 | struct cx25840_state *state = i2c_get_clientdata(client); | 389 | struct cx25840_state *state = i2c_get_clientdata(client); |
396 | 390 | ||
397 | switch (ctrl->id) { | 391 | switch (ctrl->id) { |
398 | case CX25840_CID_CARDTYPE: | 392 | case CX25840_CID_ENABLE_PVR150_WORKAROUND: |
399 | switch (ctrl->value) { | 393 | state->pvr150_workaround = ctrl->value; |
400 | case CARDTYPE_PVR150: | 394 | set_input(client, state->vid_input, state->aud_input); |
401 | case CARDTYPE_PVR150_WORKAROUND: | ||
402 | case CARDTYPE_PG600: | ||
403 | state->cardtype = ctrl->value; | ||
404 | break; | ||
405 | default: | ||
406 | return -ERANGE; | ||
407 | } | ||
408 | |||
409 | set_input(client, state->input); | ||
410 | break; | 395 | break; |
411 | 396 | ||
412 | case V4L2_CID_BRIGHTNESS: | 397 | case V4L2_CID_BRIGHTNESS: |
413 | if (ctrl->value < 0 || ctrl->value > 255) { | 398 | if (ctrl->value < 0 || ctrl->value > 255) { |
414 | cx25840_err("invalid brightness setting %d\n", | 399 | v4l_err(client, "invalid brightness setting %d\n", |
415 | ctrl->value); | 400 | ctrl->value); |
416 | return -ERANGE; | 401 | return -ERANGE; |
417 | } | 402 | } |
@@ -421,7 +406,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
421 | 406 | ||
422 | case V4L2_CID_CONTRAST: | 407 | case V4L2_CID_CONTRAST: |
423 | if (ctrl->value < 0 || ctrl->value > 127) { | 408 | if (ctrl->value < 0 || ctrl->value > 127) { |
424 | cx25840_err("invalid contrast setting %d\n", | 409 | v4l_err(client, "invalid contrast setting %d\n", |
425 | ctrl->value); | 410 | ctrl->value); |
426 | return -ERANGE; | 411 | return -ERANGE; |
427 | } | 412 | } |
@@ -431,7 +416,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
431 | 416 | ||
432 | case V4L2_CID_SATURATION: | 417 | case V4L2_CID_SATURATION: |
433 | if (ctrl->value < 0 || ctrl->value > 127) { | 418 | if (ctrl->value < 0 || ctrl->value > 127) { |
434 | cx25840_err("invalid saturation setting %d\n", | 419 | v4l_err(client, "invalid saturation setting %d\n", |
435 | ctrl->value); | 420 | ctrl->value); |
436 | return -ERANGE; | 421 | return -ERANGE; |
437 | } | 422 | } |
@@ -442,7 +427,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
442 | 427 | ||
443 | case V4L2_CID_HUE: | 428 | case V4L2_CID_HUE: |
444 | if (ctrl->value < -127 || ctrl->value > 127) { | 429 | if (ctrl->value < -127 || ctrl->value > 127) { |
445 | cx25840_err("invalid hue setting %d\n", ctrl->value); | 430 | v4l_err(client, "invalid hue setting %d\n", ctrl->value); |
446 | return -ERANGE; | 431 | return -ERANGE; |
447 | } | 432 | } |
448 | 433 | ||
@@ -455,6 +440,9 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
455 | case V4L2_CID_AUDIO_BALANCE: | 440 | case V4L2_CID_AUDIO_BALANCE: |
456 | case V4L2_CID_AUDIO_MUTE: | 441 | case V4L2_CID_AUDIO_MUTE: |
457 | return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); | 442 | return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); |
443 | |||
444 | default: | ||
445 | return -EINVAL; | ||
458 | } | 446 | } |
459 | 447 | ||
460 | return 0; | 448 | return 0; |
@@ -465,11 +453,11 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
465 | struct cx25840_state *state = i2c_get_clientdata(client); | 453 | struct cx25840_state *state = i2c_get_clientdata(client); |
466 | 454 | ||
467 | switch (ctrl->id) { | 455 | switch (ctrl->id) { |
468 | case CX25840_CID_CARDTYPE: | 456 | case CX25840_CID_ENABLE_PVR150_WORKAROUND: |
469 | ctrl->value = state->cardtype; | 457 | ctrl->value = state->pvr150_workaround; |
470 | break; | 458 | break; |
471 | case V4L2_CID_BRIGHTNESS: | 459 | case V4L2_CID_BRIGHTNESS: |
472 | ctrl->value = cx25840_read(client, 0x414) + 128; | 460 | ctrl->value = (s8)cx25840_read(client, 0x414) + 128; |
473 | break; | 461 | break; |
474 | case V4L2_CID_CONTRAST: | 462 | case V4L2_CID_CONTRAST: |
475 | ctrl->value = cx25840_read(client, 0x415) >> 1; | 463 | ctrl->value = cx25840_read(client, 0x415) >> 1; |
@@ -478,7 +466,7 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
478 | ctrl->value = cx25840_read(client, 0x420) >> 1; | 466 | ctrl->value = cx25840_read(client, 0x420) >> 1; |
479 | break; | 467 | break; |
480 | case V4L2_CID_HUE: | 468 | case V4L2_CID_HUE: |
481 | ctrl->value = cx25840_read(client, 0x422); | 469 | ctrl->value = (s8)cx25840_read(client, 0x422); |
482 | break; | 470 | break; |
483 | case V4L2_CID_AUDIO_VOLUME: | 471 | case V4L2_CID_AUDIO_VOLUME: |
484 | case V4L2_CID_AUDIO_BASS: | 472 | case V4L2_CID_AUDIO_BASS: |
@@ -527,7 +515,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | |||
527 | 515 | ||
528 | if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || | 516 | if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || |
529 | (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { | 517 | (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { |
530 | cx25840_err("%dx%d is not a valid size!\n", | 518 | v4l_err(client, "%dx%d is not a valid size!\n", |
531 | pix->width, pix->height); | 519 | pix->width, pix->height); |
532 | return -ERANGE; | 520 | return -ERANGE; |
533 | } | 521 | } |
@@ -545,7 +533,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | |||
545 | else | 533 | else |
546 | filter = 3; | 534 | filter = 3; |
547 | 535 | ||
548 | cx25840_dbg("decoder set size %dx%d -> scale %ux%u\n", | 536 | v4l_dbg(1, client, "decoder set size %dx%d -> scale %ux%u\n", |
549 | pix->width, pix->height, HSC, VSC); | 537 | pix->width, pix->height, HSC, VSC); |
550 | 538 | ||
551 | /* HSCALE=HSC */ | 539 | /* HSCALE=HSC */ |
@@ -574,17 +562,98 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | |||
574 | 562 | ||
575 | /* ----------------------------------------------------------------------- */ | 563 | /* ----------------------------------------------------------------------- */ |
576 | 564 | ||
565 | static struct v4l2_queryctrl cx25840_qctrl[] = { | ||
566 | { | ||
567 | .id = V4L2_CID_BRIGHTNESS, | ||
568 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
569 | .name = "Brightness", | ||
570 | .minimum = 0, | ||
571 | .maximum = 255, | ||
572 | .step = 1, | ||
573 | .default_value = 128, | ||
574 | .flags = 0, | ||
575 | }, { | ||
576 | .id = V4L2_CID_CONTRAST, | ||
577 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
578 | .name = "Contrast", | ||
579 | .minimum = 0, | ||
580 | .maximum = 255, | ||
581 | .step = 1, | ||
582 | .default_value = 64, | ||
583 | .flags = 0, | ||
584 | }, { | ||
585 | .id = V4L2_CID_SATURATION, | ||
586 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
587 | .name = "Saturation", | ||
588 | .minimum = 0, | ||
589 | .maximum = 255, | ||
590 | .step = 1, | ||
591 | .default_value = 64, | ||
592 | .flags = 0, | ||
593 | }, { | ||
594 | .id = V4L2_CID_HUE, | ||
595 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
596 | .name = "Hue", | ||
597 | .minimum = -128, | ||
598 | .maximum = 127, | ||
599 | .step = 1, | ||
600 | .default_value = 0, | ||
601 | .flags = 0, | ||
602 | }, { | ||
603 | .id = V4L2_CID_AUDIO_VOLUME, | ||
604 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
605 | .name = "Volume", | ||
606 | .minimum = 0, | ||
607 | .maximum = 65535, | ||
608 | .step = 65535/100, | ||
609 | .default_value = 58880, | ||
610 | .flags = 0, | ||
611 | }, { | ||
612 | .id = V4L2_CID_AUDIO_BALANCE, | ||
613 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
614 | .name = "Balance", | ||
615 | .minimum = 0, | ||
616 | .maximum = 65535, | ||
617 | .step = 65535/100, | ||
618 | .default_value = 32768, | ||
619 | .flags = 0, | ||
620 | }, { | ||
621 | .id = V4L2_CID_AUDIO_MUTE, | ||
622 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
623 | .name = "Mute", | ||
624 | .minimum = 0, | ||
625 | .maximum = 1, | ||
626 | .step = 1, | ||
627 | .default_value = 1, | ||
628 | .flags = 0, | ||
629 | }, { | ||
630 | .id = V4L2_CID_AUDIO_BASS, | ||
631 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
632 | .name = "Bass", | ||
633 | .minimum = 0, | ||
634 | .maximum = 65535, | ||
635 | .step = 65535/100, | ||
636 | .default_value = 32768, | ||
637 | }, { | ||
638 | .id = V4L2_CID_AUDIO_TREBLE, | ||
639 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
640 | .name = "Treble", | ||
641 | .minimum = 0, | ||
642 | .maximum = 65535, | ||
643 | .step = 65535/100, | ||
644 | .default_value = 32768, | ||
645 | }, | ||
646 | }; | ||
647 | |||
648 | /* ----------------------------------------------------------------------- */ | ||
649 | |||
577 | static int cx25840_command(struct i2c_client *client, unsigned int cmd, | 650 | static int cx25840_command(struct i2c_client *client, unsigned int cmd, |
578 | void *arg) | 651 | void *arg) |
579 | { | 652 | { |
580 | struct cx25840_state *state = i2c_get_clientdata(client); | 653 | struct cx25840_state *state = i2c_get_clientdata(client); |
581 | struct v4l2_tuner *vt = arg; | 654 | struct v4l2_tuner *vt = arg; |
582 | int result = 0; | ||
583 | 655 | ||
584 | switch (cmd) { | 656 | switch (cmd) { |
585 | case 0: | ||
586 | break; | ||
587 | |||
588 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 657 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
589 | /* ioctls to allow direct access to the | 658 | /* ioctls to allow direct access to the |
590 | * cx25840 registers for testing */ | 659 | * cx25840 registers for testing */ |
@@ -615,18 +684,16 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
615 | return cx25840_vbi(client, cmd, arg); | 684 | return cx25840_vbi(client, cmd, arg); |
616 | 685 | ||
617 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 686 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
618 | case AUDC_SET_INPUT: | 687 | return cx25840_audio(client, cmd, arg); |
619 | result = cx25840_audio(client, cmd, arg); | ||
620 | break; | ||
621 | 688 | ||
622 | case VIDIOC_STREAMON: | 689 | case VIDIOC_STREAMON: |
623 | cx25840_dbg("enable output\n"); | 690 | v4l_dbg(1, client, "enable output\n"); |
624 | cx25840_write(client, 0x115, 0x8c); | 691 | cx25840_write(client, 0x115, 0x8c); |
625 | cx25840_write(client, 0x116, 0x07); | 692 | cx25840_write(client, 0x116, 0x07); |
626 | break; | 693 | break; |
627 | 694 | ||
628 | case VIDIOC_STREAMOFF: | 695 | case VIDIOC_STREAMOFF: |
629 | cx25840_dbg("disable output\n"); | 696 | v4l_dbg(1, client, "disable output\n"); |
630 | cx25840_write(client, 0x115, 0x00); | 697 | cx25840_write(client, 0x115, 0x00); |
631 | cx25840_write(client, 0x116, 0x00); | 698 | cx25840_write(client, 0x116, 0x00); |
632 | break; | 699 | break; |
@@ -636,28 +703,58 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
636 | break; | 703 | break; |
637 | 704 | ||
638 | case VIDIOC_G_CTRL: | 705 | case VIDIOC_G_CTRL: |
639 | result = get_v4lctrl(client, (struct v4l2_control *)arg); | 706 | return get_v4lctrl(client, (struct v4l2_control *)arg); |
640 | break; | ||
641 | 707 | ||
642 | case VIDIOC_S_CTRL: | 708 | case VIDIOC_S_CTRL: |
643 | result = set_v4lctrl(client, (struct v4l2_control *)arg); | 709 | return set_v4lctrl(client, (struct v4l2_control *)arg); |
644 | break; | 710 | |
711 | case VIDIOC_QUERYCTRL: | ||
712 | { | ||
713 | struct v4l2_queryctrl *qc = arg; | ||
714 | int i; | ||
715 | |||
716 | for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) | ||
717 | if (qc->id && qc->id == cx25840_qctrl[i].id) { | ||
718 | memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); | ||
719 | return 0; | ||
720 | } | ||
721 | return -EINVAL; | ||
722 | } | ||
645 | 723 | ||
646 | case VIDIOC_G_STD: | 724 | case VIDIOC_G_STD: |
647 | *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); | 725 | *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); |
648 | break; | 726 | break; |
649 | 727 | ||
650 | case VIDIOC_S_STD: | 728 | case VIDIOC_S_STD: |
651 | result = set_v4lstd(client, *(v4l2_std_id *)arg); | 729 | state->radio = 0; |
730 | return set_v4lstd(client, *(v4l2_std_id *)arg); | ||
731 | |||
732 | case AUDC_SET_RADIO: | ||
733 | state->radio = 1; | ||
652 | break; | 734 | break; |
653 | 735 | ||
654 | case VIDIOC_G_INPUT: | 736 | case VIDIOC_G_INPUT: |
655 | *(int *)arg = state->input; | 737 | *(int *)arg = state->vid_input; |
656 | break; | 738 | break; |
657 | 739 | ||
658 | case VIDIOC_S_INPUT: | 740 | case VIDIOC_S_INPUT: |
659 | result = set_input(client, *(int *)arg); | 741 | return set_input(client, *(enum cx25840_video_input *)arg, state->aud_input); |
742 | |||
743 | case VIDIOC_S_AUDIO: | ||
744 | { | ||
745 | struct v4l2_audio *input = arg; | ||
746 | |||
747 | return set_input(client, state->vid_input, input->index); | ||
748 | } | ||
749 | |||
750 | case VIDIOC_G_AUDIO: | ||
751 | { | ||
752 | struct v4l2_audio *input = arg; | ||
753 | |||
754 | memset(input, 0, sizeof(*input)); | ||
755 | input->index = state->aud_input; | ||
660 | break; | 756 | break; |
757 | } | ||
661 | 758 | ||
662 | case VIDIOC_S_FREQUENCY: | 759 | case VIDIOC_S_FREQUENCY: |
663 | input_change(client); | 760 | input_change(client); |
@@ -670,6 +767,9 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
670 | u8 vpres = cx25840_read(client, 0x80a) & 0x10; | 767 | u8 vpres = cx25840_read(client, 0x80a) & 0x10; |
671 | int val = 0; | 768 | int val = 0; |
672 | 769 | ||
770 | if (state->radio) | ||
771 | break; | ||
772 | |||
673 | vt->capability |= | 773 | vt->capability |= |
674 | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | | 774 | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | |
675 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; | 775 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; |
@@ -724,12 +824,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
724 | break; | 824 | break; |
725 | 825 | ||
726 | case VIDIOC_G_FMT: | 826 | case VIDIOC_G_FMT: |
727 | result = get_v4lfmt(client, (struct v4l2_format *)arg); | 827 | return get_v4lfmt(client, (struct v4l2_format *)arg); |
728 | break; | ||
729 | 828 | ||
730 | case VIDIOC_S_FMT: | 829 | case VIDIOC_S_FMT: |
731 | result = set_v4lfmt(client, (struct v4l2_format *)arg); | 830 | return set_v4lfmt(client, (struct v4l2_format *)arg); |
732 | break; | ||
733 | 831 | ||
734 | case VIDIOC_INT_RESET: | 832 | case VIDIOC_INT_RESET: |
735 | cx25840_initialize(client, 0); | 833 | cx25840_initialize(client, 0); |
@@ -741,11 +839,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
741 | break; | 839 | break; |
742 | 840 | ||
743 | default: | 841 | default: |
744 | cx25840_err("invalid ioctl %x\n", cmd); | ||
745 | return -EINVAL; | 842 | return -EINVAL; |
746 | } | 843 | } |
747 | 844 | ||
748 | return result; | 845 | return 0; |
749 | } | 846 | } |
750 | 847 | ||
751 | /* ----------------------------------------------------------------------- */ | 848 | /* ----------------------------------------------------------------------- */ |
@@ -775,7 +872,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
775 | client->driver = &i2c_driver_cx25840; | 872 | client->driver = &i2c_driver_cx25840; |
776 | snprintf(client->name, sizeof(client->name) - 1, "cx25840"); | 873 | snprintf(client->name, sizeof(client->name) - 1, "cx25840"); |
777 | 874 | ||
778 | cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1); | 875 | v4l_dbg(1, client, "detecting cx25840 client on address 0x%x\n", address << 1); |
779 | 876 | ||
780 | device_id = cx25840_read(client, 0x101) << 8; | 877 | device_id = cx25840_read(client, 0x101) << 8; |
781 | device_id |= cx25840_read(client, 0x100); | 878 | device_id |= cx25840_read(client, 0x100); |
@@ -783,12 +880,12 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
783 | /* The high byte of the device ID should be | 880 | /* The high byte of the device ID should be |
784 | * 0x84 if chip is present */ | 881 | * 0x84 if chip is present */ |
785 | if ((device_id & 0xff00) != 0x8400) { | 882 | if ((device_id & 0xff00) != 0x8400) { |
786 | cx25840_dbg("cx25840 not found\n"); | 883 | v4l_dbg(1, client, "cx25840 not found\n"); |
787 | kfree(client); | 884 | kfree(client); |
788 | return 0; | 885 | return 0; |
789 | } | 886 | } |
790 | 887 | ||
791 | cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n", | 888 | v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", |
792 | (device_id & 0xfff0) >> 4, | 889 | (device_id & 0xfff0) >> 4, |
793 | (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, | 890 | (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, |
794 | address << 1, adapter->name); | 891 | address << 1, adapter->name); |
@@ -801,10 +898,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
801 | 898 | ||
802 | i2c_set_clientdata(client, state); | 899 | i2c_set_clientdata(client, state); |
803 | memset(state, 0, sizeof(struct cx25840_state)); | 900 | memset(state, 0, sizeof(struct cx25840_state)); |
804 | state->input = CX25840_TUNER; | 901 | state->vid_input = CX25840_COMPOSITE7; |
805 | state->audclk_freq = V4L2_AUDCLK_48_KHZ; | 902 | state->aud_input = CX25840_AUDIO8; |
806 | state->audio_input = AUDIO_TUNER; | 903 | state->audclk_freq = 48000; |
807 | state->cardtype = CARDTYPE_PVR150; | 904 | state->pvr150_workaround = 0; |
808 | 905 | ||
809 | cx25840_initialize(client, 1); | 906 | cx25840_initialize(client, 1); |
810 | 907 | ||
@@ -815,11 +912,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
815 | 912 | ||
816 | static int cx25840_attach_adapter(struct i2c_adapter *adapter) | 913 | static int cx25840_attach_adapter(struct i2c_adapter *adapter) |
817 | { | 914 | { |
818 | #ifdef I2C_CLASS_TV_ANALOG | ||
819 | if (adapter->class & I2C_CLASS_TV_ANALOG) | 915 | if (adapter->class & I2C_CLASS_TV_ANALOG) |
820 | #else | ||
821 | if (adapter->id == I2C_HW_B_BT848) | ||
822 | #endif | ||
823 | return i2c_probe(adapter, &addr_data, &cx25840_detect_client); | 916 | return i2c_probe(adapter, &addr_data, &cx25840_detect_client); |
824 | return 0; | 917 | return 0; |
825 | } | 918 | } |
@@ -846,9 +939,7 @@ static struct i2c_driver i2c_driver_cx25840 = { | |||
846 | .driver = { | 939 | .driver = { |
847 | .name = "cx25840", | 940 | .name = "cx25840", |
848 | }, | 941 | }, |
849 | |||
850 | .id = I2C_DRIVERID_CX25840, | 942 | .id = I2C_DRIVERID_CX25840, |
851 | |||
852 | .attach_adapter = cx25840_attach_adapter, | 943 | .attach_adapter = cx25840_attach_adapter, |
853 | .detach_client = cx25840_detach_client, | 944 | .detach_client = cx25840_detach_client, |
854 | .command = cx25840_command, | 945 | .command = cx25840_command, |
@@ -892,11 +983,13 @@ static void log_status(struct i2c_client *client) | |||
892 | u8 pref_mode = cx25840_read(client, 0x809); | 983 | u8 pref_mode = cx25840_read(client, 0x809); |
893 | u8 afc0 = cx25840_read(client, 0x80b); | 984 | u8 afc0 = cx25840_read(client, 0x80b); |
894 | u8 mute_ctl = cx25840_read(client, 0x8d3); | 985 | u8 mute_ctl = cx25840_read(client, 0x8d3); |
986 | int vid_input = state->vid_input; | ||
987 | int aud_input = state->aud_input; | ||
895 | char *p; | 988 | char *p; |
896 | 989 | ||
897 | cx25840_info("Video signal: %spresent\n", | 990 | v4l_info(client, "Video signal: %spresent\n", |
898 | (microctrl_vidfmt & 0x10) ? "" : "not "); | 991 | (microctrl_vidfmt & 0x10) ? "" : "not "); |
899 | cx25840_info("Detected format: %s\n", | 992 | v4l_info(client, "Detected format: %s\n", |
900 | fmt_strs[gen_stat1 & 0xf]); | 993 | fmt_strs[gen_stat1 & 0xf]); |
901 | 994 | ||
902 | switch (mod_det_stat0) { | 995 | switch (mod_det_stat0) { |
@@ -911,7 +1004,7 @@ static void log_status(struct i2c_client *client) | |||
911 | case 0xfe: p = "forced mode"; break; | 1004 | case 0xfe: p = "forced mode"; break; |
912 | default: p = "not defined"; | 1005 | default: p = "not defined"; |
913 | } | 1006 | } |
914 | cx25840_info("Detected audio mode: %s\n", p); | 1007 | v4l_info(client, "Detected audio mode: %s\n", p); |
915 | 1008 | ||
916 | switch (mod_det_stat1) { | 1009 | switch (mod_det_stat1) { |
917 | case 0x00: p = "not defined"; break; | 1010 | case 0x00: p = "not defined"; break; |
@@ -937,10 +1030,10 @@ static void log_status(struct i2c_client *client) | |||
937 | case 0xff: p = "no detected audio standard"; break; | 1030 | case 0xff: p = "no detected audio standard"; break; |
938 | default: p = "not defined"; | 1031 | default: p = "not defined"; |
939 | } | 1032 | } |
940 | cx25840_info("Detected audio standard: %s\n", p); | 1033 | v4l_info(client, "Detected audio standard: %s\n", p); |
941 | cx25840_info("Audio muted: %s\n", | 1034 | v4l_info(client, "Audio muted: %s\n", |
942 | (mute_ctl & 0x2) ? "yes" : "no"); | 1035 | (mute_ctl & 0x2) ? "yes" : "no"); |
943 | cx25840_info("Audio microcontroller: %s\n", | 1036 | v4l_info(client, "Audio microcontroller: %s\n", |
944 | (download_ctl & 0x10) ? "running" : "stopped"); | 1037 | (download_ctl & 0x10) ? "running" : "stopped"); |
945 | 1038 | ||
946 | switch (audio_config >> 4) { | 1039 | switch (audio_config >> 4) { |
@@ -962,7 +1055,7 @@ static void log_status(struct i2c_client *client) | |||
962 | case 0x0f: p = "automatic detection"; break; | 1055 | case 0x0f: p = "automatic detection"; break; |
963 | default: p = "undefined"; | 1056 | default: p = "undefined"; |
964 | } | 1057 | } |
965 | cx25840_info("Configured audio standard: %s\n", p); | 1058 | v4l_info(client, "Configured audio standard: %s\n", p); |
966 | 1059 | ||
967 | if ((audio_config >> 4) < 0xF) { | 1060 | if ((audio_config >> 4) < 0xF) { |
968 | switch (audio_config & 0xF) { | 1061 | switch (audio_config & 0xF) { |
@@ -979,7 +1072,7 @@ static void log_status(struct i2c_client *client) | |||
979 | case 0x0a: p = "SAP"; break; | 1072 | case 0x0a: p = "SAP"; break; |
980 | default: p = "undefined"; | 1073 | default: p = "undefined"; |
981 | } | 1074 | } |
982 | cx25840_info("Configured audio mode: %s\n", p); | 1075 | v4l_info(client, "Configured audio mode: %s\n", p); |
983 | } else { | 1076 | } else { |
984 | switch (audio_config & 0xF) { | 1077 | switch (audio_config & 0xF) { |
985 | case 0x00: p = "BG"; break; | 1078 | case 0x00: p = "BG"; break; |
@@ -995,30 +1088,27 @@ static void log_status(struct i2c_client *client) | |||
995 | case 0x0f: p = "automatic standard and mode detection"; break; | 1088 | case 0x0f: p = "automatic standard and mode detection"; break; |
996 | default: p = "undefined"; | 1089 | default: p = "undefined"; |
997 | } | 1090 | } |
998 | cx25840_info("Configured audio system: %s\n", p); | 1091 | v4l_info(client, "Configured audio system: %s\n", p); |
999 | } | 1092 | } |
1000 | 1093 | ||
1001 | cx25840_info("Specified standard: %s\n", | 1094 | v4l_info(client, "Specified standard: %s\n", |
1002 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); | 1095 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); |
1003 | 1096 | ||
1004 | switch (state->input) { | 1097 | if (vid_input >= CX25840_COMPOSITE1 && |
1005 | case CX25840_COMPOSITE0: p = "Composite 0"; break; | 1098 | vid_input <= CX25840_COMPOSITE8) { |
1006 | case CX25840_COMPOSITE1: p = "Composite 1"; break; | 1099 | v4l_info(client, "Specified video input: Composite %d\n", |
1007 | case CX25840_SVIDEO0: p = "S-Video 0"; break; | 1100 | vid_input - CX25840_COMPOSITE1 + 1); |
1008 | case CX25840_SVIDEO1: p = "S-Video 1"; break; | 1101 | } else { |
1009 | case CX25840_TUNER: p = "Tuner"; break; | 1102 | v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", |
1103 | (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); | ||
1010 | } | 1104 | } |
1011 | cx25840_info("Specified input: %s\n", p); | 1105 | if (aud_input) { |
1012 | cx25840_info("Specified audio input: %s\n", | 1106 | v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); |
1013 | state->audio_input == 0 ? "Tuner" : "External"); | 1107 | } else { |
1014 | 1108 | v4l_info(client, "Specified audio input: External\n"); | |
1015 | switch (state->audclk_freq) { | ||
1016 | case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break; | ||
1017 | case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break; | ||
1018 | case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break; | ||
1019 | default: p = "undefined"; | ||
1020 | } | 1109 | } |
1021 | cx25840_info("Specified audioclock freq: %s\n", p); | 1110 | |
1111 | v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); | ||
1022 | 1112 | ||
1023 | switch (pref_mode & 0xf) { | 1113 | switch (pref_mode & 0xf) { |
1024 | case 0: p = "mono/language A"; break; | 1114 | case 0: p = "mono/language A"; break; |
@@ -1031,7 +1121,7 @@ static void log_status(struct i2c_client *client) | |||
1031 | case 7: p = "language AB"; break; | 1121 | case 7: p = "language AB"; break; |
1032 | default: p = "undefined"; | 1122 | default: p = "undefined"; |
1033 | } | 1123 | } |
1034 | cx25840_info("Preferred audio mode: %s\n", p); | 1124 | v4l_info(client, "Preferred audio mode: %s\n", p); |
1035 | 1125 | ||
1036 | if ((audio_config & 0xf) == 0xf) { | 1126 | if ((audio_config & 0xf) == 0xf) { |
1037 | switch ((afc0 >> 3) & 0x3) { | 1127 | switch ((afc0 >> 3) & 0x3) { |
@@ -1040,7 +1130,7 @@ static void log_status(struct i2c_client *client) | |||
1040 | case 2: p = "autodetect"; break; | 1130 | case 2: p = "autodetect"; break; |
1041 | default: p = "undefined"; | 1131 | default: p = "undefined"; |
1042 | } | 1132 | } |
1043 | cx25840_info("Selected 65 MHz format: %s\n", p); | 1133 | v4l_info(client, "Selected 65 MHz format: %s\n", p); |
1044 | 1134 | ||
1045 | switch (afc0 & 0x7) { | 1135 | switch (afc0 & 0x7) { |
1046 | case 0: p = "chroma"; break; | 1136 | case 0: p = "chroma"; break; |
@@ -1050,6 +1140,6 @@ static void log_status(struct i2c_client *client) | |||
1050 | case 4: p = "autodetect"; break; | 1140 | case 4: p = "autodetect"; break; |
1051 | default: p = "undefined"; | 1141 | default: p = "undefined"; |
1052 | } | 1142 | } |
1053 | cx25840_info("Selected 45 MHz format: %s\n", p); | 1143 | v4l_info(client, "Selected 45 MHz format: %s\n", p); |
1054 | } | 1144 | } |
1055 | } | 1145 | } |
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index df9d50a75542..e1a7823d82cd 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | |||
19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
20 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
21 | #include <linux/i2c-algo-bit.h> | 20 | #include <linux/i2c-algo-bit.h> |
@@ -38,7 +37,7 @@ module_param(firmware, charp, 0444); | |||
38 | MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); | 37 | MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); |
39 | MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); | 38 | MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); |
40 | 39 | ||
41 | static inline void set_i2c_delay(struct i2c_client *client, int delay) | 40 | static void set_i2c_delay(struct i2c_client *client, int delay) |
42 | { | 41 | { |
43 | struct i2c_algo_bit_data *algod = client->adapter->algo_data; | 42 | struct i2c_algo_bit_data *algod = client->adapter->algo_data; |
44 | 43 | ||
@@ -52,7 +51,7 @@ static inline void set_i2c_delay(struct i2c_client *client, int delay) | |||
52 | } | 51 | } |
53 | } | 52 | } |
54 | 53 | ||
55 | static inline void start_fw_load(struct i2c_client *client) | 54 | static void start_fw_load(struct i2c_client *client) |
56 | { | 55 | { |
57 | /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ | 56 | /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ |
58 | cx25840_write(client, 0x800, 0x00); | 57 | cx25840_write(client, 0x800, 0x00); |
@@ -66,7 +65,7 @@ static inline void start_fw_load(struct i2c_client *client) | |||
66 | set_i2c_delay(client, 3); | 65 | set_i2c_delay(client, 3); |
67 | } | 66 | } |
68 | 67 | ||
69 | static inline void end_fw_load(struct i2c_client *client) | 68 | static void end_fw_load(struct i2c_client *client) |
70 | { | 69 | { |
71 | if (fastfw) | 70 | if (fastfw) |
72 | set_i2c_delay(client, 10); | 71 | set_i2c_delay(client, 10); |
@@ -77,38 +76,47 @@ static inline void end_fw_load(struct i2c_client *client) | |||
77 | cx25840_write(client, 0x803, 0x03); | 76 | cx25840_write(client, 0x803, 0x03); |
78 | } | 77 | } |
79 | 78 | ||
80 | static inline int check_fw_load(struct i2c_client *client, int size) | 79 | static int check_fw_load(struct i2c_client *client, int size) |
81 | { | 80 | { |
82 | /* DL_ADDR_HB DL_ADDR_LB */ | 81 | /* DL_ADDR_HB DL_ADDR_LB */ |
83 | int s = cx25840_read(client, 0x801) << 8; | 82 | int s = cx25840_read(client, 0x801) << 8; |
84 | s |= cx25840_read(client, 0x800); | 83 | s |= cx25840_read(client, 0x800); |
85 | 84 | ||
86 | if (size != s) { | 85 | if (size != s) { |
87 | cx25840_err("firmware %s load failed\n", firmware); | 86 | v4l_err(client, "firmware %s load failed\n", firmware); |
88 | return -EINVAL; | 87 | return -EINVAL; |
89 | } | 88 | } |
90 | 89 | ||
91 | cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size); | 90 | v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); |
92 | return 0; | 91 | return 0; |
93 | } | 92 | } |
94 | 93 | ||
95 | static inline int fw_write(struct i2c_client *client, u8 * data, int size) | 94 | static int fw_write(struct i2c_client *client, u8 * data, int size) |
96 | { | 95 | { |
97 | if (i2c_master_send(client, data, size) < size) { | 96 | int sent; |
97 | |||
98 | if ((sent = i2c_master_send(client, data, size)) < size) { | ||
98 | 99 | ||
99 | if (fastfw) { | 100 | if (fastfw) { |
100 | cx25840_err("333MHz i2c firmware load failed\n"); | 101 | v4l_err(client, "333MHz i2c firmware load failed\n"); |
101 | fastfw = 0; | 102 | fastfw = 0; |
102 | set_i2c_delay(client, 10); | 103 | set_i2c_delay(client, 10); |
103 | 104 | ||
105 | if (sent > 2) { | ||
106 | u16 dl_addr = cx25840_read(client, 0x801) << 8; | ||
107 | dl_addr |= cx25840_read(client, 0x800); | ||
108 | dl_addr -= sent - 2; | ||
109 | cx25840_write(client, 0x801, dl_addr >> 8); | ||
110 | cx25840_write(client, 0x800, dl_addr & 0xff); | ||
111 | } | ||
112 | |||
104 | if (i2c_master_send(client, data, size) < size) { | 113 | if (i2c_master_send(client, data, size) < size) { |
105 | cx25840_err | 114 | v4l_err(client, "100MHz i2c firmware load failed\n"); |
106 | ("100MHz i2c firmware load failed\n"); | ||
107 | return -ENOSYS; | 115 | return -ENOSYS; |
108 | } | 116 | } |
109 | 117 | ||
110 | } else { | 118 | } else { |
111 | cx25840_err("firmware load i2c failure\n"); | 119 | v4l_err(client, "firmware load i2c failure\n"); |
112 | return -ENOSYS; | 120 | return -ENOSYS; |
113 | } | 121 | } |
114 | 122 | ||
@@ -124,7 +132,7 @@ int cx25840_loadfw(struct i2c_client *client) | |||
124 | int size, send, retval; | 132 | int size, send, retval; |
125 | 133 | ||
126 | if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { | 134 | if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { |
127 | cx25840_err("unable to open firmware %s\n", firmware); | 135 | v4l_err(client, "unable to open firmware %s\n", firmware); |
128 | return -EINVAL; | 136 | return -EINVAL; |
129 | } | 137 | } |
130 | 138 | ||
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 13ba4e15ddea..04d879da7d63 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | #include "cx25840.h" | 23 | #include "cx25840.h" |
24 | 24 | ||
25 | static inline int odd_parity(u8 c) | 25 | static int odd_parity(u8 c) |
26 | { | 26 | { |
27 | c ^= (c >> 4); | 27 | c ^= (c >> 4); |
28 | c ^= (c >> 2); | 28 | c ^= (c >> 2); |
@@ -31,7 +31,7 @@ static inline int odd_parity(u8 c) | |||
31 | return c & 1; | 31 | return c & 1; |
32 | } | 32 | } |
33 | 33 | ||
34 | static inline int decode_vps(u8 * dst, u8 * p) | 34 | static int decode_vps(u8 * dst, u8 * p) |
35 | { | 35 | { |
36 | static const u8 biphase_tbl[] = { | 36 | static const u8 biphase_tbl[] = { |
37 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, | 37 | 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, |
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h index 40aa59f9c525..fd22f30dcc1b 100644 --- a/drivers/media/video/cx25840/cx25840.h +++ b/drivers/media/video/cx25840/cx25840.h | |||
@@ -24,48 +24,60 @@ | |||
24 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | 26 | ||
27 | extern int cx25840_debug; | 27 | /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is |
28 | 28 | present in Hauppauge PVR-150 (and possibly PVR-500) cards that have | |
29 | #define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \ | 29 | certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The |
30 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
31 | client->driver->driver.name, \ | ||
32 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
33 | |||
34 | #define cx25840_err(fmt, arg...) do { \ | ||
35 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
36 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
37 | |||
38 | #define cx25840_info(fmt, arg...) do { \ | ||
39 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
40 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
41 | |||
42 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) | ||
43 | |||
44 | /* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a | ||
45 | hardware bug that is present in PVR150 (and possible PVR500) cards that | ||
46 | have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The | ||
47 | audio autodetect fails on some channels for these models and the workaround | 30 | audio autodetect fails on some channels for these models and the workaround |
48 | is to select the audio standard explicitly. Many thanks to Hauppauge for | 31 | is to select the audio standard explicitly. Many thanks to Hauppauge for |
49 | providing this information. */ | 32 | providing this information. */ |
50 | enum cx25840_cardtype { | 33 | #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) |
51 | CARDTYPE_PVR150, | 34 | |
52 | CARDTYPE_PG600, | 35 | enum cx25840_video_input { |
53 | CARDTYPE_PVR150_WORKAROUND, | 36 | /* Composite video inputs In1-In8 */ |
37 | CX25840_COMPOSITE1 = 1, | ||
38 | CX25840_COMPOSITE2, | ||
39 | CX25840_COMPOSITE3, | ||
40 | CX25840_COMPOSITE4, | ||
41 | CX25840_COMPOSITE5, | ||
42 | CX25840_COMPOSITE6, | ||
43 | CX25840_COMPOSITE7, | ||
44 | CX25840_COMPOSITE8, | ||
45 | |||
46 | /* S-Video inputs consist of one luma input (In1-In4) ORed with one | ||
47 | chroma input (In5-In8) */ | ||
48 | CX25840_SVIDEO_LUMA1 = 0x10, | ||
49 | CX25840_SVIDEO_LUMA2 = 0x20, | ||
50 | CX25840_SVIDEO_LUMA3 = 0x30, | ||
51 | CX25840_SVIDEO_LUMA4 = 0x40, | ||
52 | CX25840_SVIDEO_CHROMA4 = 0x400, | ||
53 | CX25840_SVIDEO_CHROMA5 = 0x500, | ||
54 | CX25840_SVIDEO_CHROMA6 = 0x600, | ||
55 | CX25840_SVIDEO_CHROMA7 = 0x700, | ||
56 | CX25840_SVIDEO_CHROMA8 = 0x800, | ||
57 | |||
58 | /* S-Video aliases for common luma/chroma combinations */ | ||
59 | CX25840_SVIDEO1 = 0x510, | ||
60 | CX25840_SVIDEO2 = 0x620, | ||
61 | CX25840_SVIDEO3 = 0x730, | ||
62 | CX25840_SVIDEO4 = 0x840, | ||
54 | }; | 63 | }; |
55 | 64 | ||
56 | enum cx25840_input { | 65 | enum cx25840_audio_input { |
57 | CX25840_TUNER, | 66 | /* Audio inputs: serial or In4-In8 */ |
58 | CX25840_COMPOSITE0, | 67 | CX25840_AUDIO_SERIAL, |
59 | CX25840_COMPOSITE1, | 68 | CX25840_AUDIO4 = 4, |
60 | CX25840_SVIDEO0, | 69 | CX25840_AUDIO5, |
61 | CX25840_SVIDEO1 | 70 | CX25840_AUDIO6, |
71 | CX25840_AUDIO7, | ||
72 | CX25840_AUDIO8, | ||
62 | }; | 73 | }; |
63 | 74 | ||
64 | struct cx25840_state { | 75 | struct cx25840_state { |
65 | enum cx25840_cardtype cardtype; | 76 | int pvr150_workaround; |
66 | enum cx25840_input input; | 77 | int radio; |
67 | int audio_input; | 78 | enum cx25840_video_input vid_input; |
68 | enum v4l2_audio_clock_freq audclk_freq; | 79 | enum cx25840_audio_input aud_input; |
80 | u32 audclk_freq; | ||
69 | }; | 81 | }; |
70 | 82 | ||
71 | /* ----------------------------------------------------------------------- */ | 83 | /* ----------------------------------------------------------------------- */ |
@@ -84,6 +96,7 @@ int cx25840_loadfw(struct i2c_client *client); | |||
84 | /* ----------------------------------------------------------------------- */ | 96 | /* ----------------------------------------------------------------------- */ |
85 | /* cx25850-audio.c */ | 97 | /* cx25850-audio.c */ |
86 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); | 98 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); |
99 | void cx25840_audio_set_path(struct i2c_client *client); | ||
87 | 100 | ||
88 | /* ----------------------------------------------------------------------- */ | 101 | /* ----------------------------------------------------------------------- */ |
89 | /* cx25850-vbi.c */ | 102 | /* cx25850-vbi.c */ |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 85ba4106dc79..76fcb4e995c9 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -29,6 +29,21 @@ config VIDEO_CX88_DVB | |||
29 | You must also select one or more DVB/ATSC demodulators. | 29 | You must also select one or more DVB/ATSC demodulators. |
30 | If you are unsure which you need, choose all of them. | 30 | If you are unsure which you need, choose all of them. |
31 | 31 | ||
32 | config VIDEO_CX88_ALSA | ||
33 | tristate "ALSA DMA audio support" | ||
34 | depends on VIDEO_CX88 && SND | ||
35 | select SND_PCM_OSS | ||
36 | ---help--- | ||
37 | This is a video4linux driver for direct (DMA) audio on | ||
38 | Conexant 2388x based TV cards. | ||
39 | It only works with boards with function 01 enabled. | ||
40 | To check if your board supports, use lspci -n. | ||
41 | If supported, you should see 1471:8801 or 1471:8811 | ||
42 | PCI device. | ||
43 | |||
44 | To compile this driver as a module, choose M here: the | ||
45 | module will be called cx88-alsa. | ||
46 | |||
32 | config VIDEO_CX88_DVB_ALL_FRONTENDS | 47 | config VIDEO_CX88_DVB_ALL_FRONTENDS |
33 | bool "Build all supported frontends for cx2388x based TV cards" | 48 | bool "Build all supported frontends for cx2388x based TV cards" |
34 | default y | 49 | default y |
@@ -38,6 +53,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS | |||
38 | select DVB_CX22702 | 53 | select DVB_CX22702 |
39 | select DVB_LGDT330X | 54 | select DVB_LGDT330X |
40 | select DVB_NXT200X | 55 | select DVB_NXT200X |
56 | select DVB_CX24123 | ||
41 | ---help--- | 57 | ---help--- |
42 | This builds cx88-dvb with all currently supported frontend | 58 | This builds cx88-dvb with all currently supported frontend |
43 | demodulators. If you wish to tweak your configuration, and | 59 | demodulators. If you wish to tweak your configuration, and |
@@ -89,3 +105,12 @@ config VIDEO_CX88_DVB_NXT200X | |||
89 | ---help--- | 105 | ---help--- |
90 | This adds ATSC 8VSB and QAM64/256 support for cards based on the | 106 | This adds ATSC 8VSB and QAM64/256 support for cards based on the |
91 | Connexant 2388x chip and the NXT2002/NXT2004 demodulator. | 107 | Connexant 2388x chip and the NXT2002/NXT2004 demodulator. |
108 | |||
109 | config VIDEO_CX88_DVB_CX24123 | ||
110 | bool "Conexant CX24123 DVB-S Support" | ||
111 | default y | ||
112 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
113 | select DVB_CX24123 | ||
114 | ---help--- | ||
115 | This adds DVB-S support for cards based on the | ||
116 | Connexant 2388x chip and the CX24123 demodulator. | ||
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 54401b02b7ce..e4b2134fe567 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -4,7 +4,7 @@ cx8800-objs := cx88-video.o cx88-vbi.o | |||
4 | cx8802-objs := cx88-mpeg.o | 4 | cx8802-objs := cx88-mpeg.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o | 6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o |
7 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o | 7 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o |
8 | 8 | ||
9 | EXTRA_CFLAGS += -I$(src)/.. | 9 | EXTRA_CFLAGS += -I$(src)/.. |
10 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 10 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
@@ -16,5 +16,7 @@ extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 | |||
16 | extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 | 16 | extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 |
17 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 | 17 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 |
18 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 | 18 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 |
19 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 | ||
20 | extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1 | ||
19 | 21 | ||
20 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) | 22 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c new file mode 100644 index 000000000000..7695b521eb35 --- /dev/null +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -0,0 +1,848 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Support for audio capture | ||
4 | * PCI function #1 of the cx2388x. | ||
5 | * | ||
6 | * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> | ||
7 | * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
8 | * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> | ||
9 | * Based on dummy.c by Jaroslav Kysela <perex@suse.cz> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <asm/delay.h> | ||
31 | #include <sound/driver.h> | ||
32 | #include <sound/core.h> | ||
33 | #include <sound/pcm.h> | ||
34 | #include <sound/pcm_params.h> | ||
35 | #include <sound/control.h> | ||
36 | #include <sound/initval.h> | ||
37 | |||
38 | #include "cx88.h" | ||
39 | #include "cx88-reg.h" | ||
40 | |||
41 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | ||
42 | printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg) | ||
43 | |||
44 | #define dprintk_core(level,fmt, arg...) if (debug >= level) \ | ||
45 | printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg) | ||
46 | |||
47 | |||
48 | /**************************************************************************** | ||
49 | Data type declarations - Can be moded to a header file later | ||
50 | ****************************************************************************/ | ||
51 | |||
52 | /* These can be replaced after done */ | ||
53 | #define MIXER_ADDR_LAST MAX_CX88_INPUT | ||
54 | |||
55 | struct cx88_audio_dev { | ||
56 | struct cx88_core *core; | ||
57 | struct cx88_dmaqueue q; | ||
58 | |||
59 | /* pci i/o */ | ||
60 | struct pci_dev *pci; | ||
61 | unsigned char pci_rev,pci_lat; | ||
62 | |||
63 | /* audio controls */ | ||
64 | int irq; | ||
65 | |||
66 | snd_card_t *card; | ||
67 | |||
68 | spinlock_t reg_lock; | ||
69 | |||
70 | unsigned int dma_size; | ||
71 | unsigned int period_size; | ||
72 | unsigned int num_periods; | ||
73 | |||
74 | struct videobuf_dmabuf dma_risc; | ||
75 | |||
76 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | ||
77 | int capture_source[MIXER_ADDR_LAST+1][2]; | ||
78 | |||
79 | long int read_count; | ||
80 | long int read_offset; | ||
81 | |||
82 | struct cx88_buffer *buf; | ||
83 | |||
84 | long opened; | ||
85 | snd_pcm_substream_t *substream; | ||
86 | |||
87 | }; | ||
88 | typedef struct cx88_audio_dev snd_cx88_card_t; | ||
89 | |||
90 | |||
91 | |||
92 | /**************************************************************************** | ||
93 | Module global static vars | ||
94 | ****************************************************************************/ | ||
95 | |||
96 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
97 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
98 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; | ||
99 | static snd_card_t *snd_cx88_cards[SNDRV_CARDS]; | ||
100 | |||
101 | module_param_array(enable, bool, NULL, 0444); | ||
102 | MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); | ||
103 | |||
104 | module_param_array(index, int, NULL, 0444); | ||
105 | MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); | ||
106 | |||
107 | |||
108 | /**************************************************************************** | ||
109 | Module macros | ||
110 | ****************************************************************************/ | ||
111 | |||
112 | MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); | ||
113 | MODULE_AUTHOR("Ricardo Cerqueira"); | ||
114 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>"); | ||
115 | MODULE_LICENSE("GPL"); | ||
116 | MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," | ||
117 | "{{Conexant,23882}," | ||
118 | "{{Conexant,23883}"); | ||
119 | static unsigned int debug = 0; | ||
120 | module_param(debug,int,0644); | ||
121 | MODULE_PARM_DESC(debug,"enable debug messages"); | ||
122 | |||
123 | /**************************************************************************** | ||
124 | Module specific funtions | ||
125 | ****************************************************************************/ | ||
126 | |||
127 | /* | ||
128 | * BOARD Specific: Sets audio DMA | ||
129 | */ | ||
130 | |||
131 | int _cx88_start_audio_dma(snd_cx88_card_t *chip) | ||
132 | { | ||
133 | struct cx88_buffer *buf = chip->buf; | ||
134 | struct cx88_core *core=chip->core; | ||
135 | struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25]; | ||
136 | |||
137 | |||
138 | dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start); | ||
139 | |||
140 | /* setup fifo + format - out channel */ | ||
141 | cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25], | ||
142 | buf->bpl, buf->risc.dma); | ||
143 | |||
144 | /* sets bpl size */ | ||
145 | cx_write(MO_AUDD_LNGTH, buf->bpl); | ||
146 | |||
147 | /* reset counter */ | ||
148 | cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET); | ||
149 | |||
150 | dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02)); | ||
151 | /* enable irqs */ | ||
152 | cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02); | ||
153 | |||
154 | |||
155 | /* Enables corresponding bits at AUD_INT_STAT */ | ||
156 | cx_write(MO_AUD_INTMSK, | ||
157 | (1<<16)| | ||
158 | (1<<12)| | ||
159 | (1<<4)| | ||
160 | (1<<0) | ||
161 | ); | ||
162 | |||
163 | /* start dma */ | ||
164 | cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */ | ||
165 | cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */ | ||
166 | |||
167 | if (debug) | ||
168 | cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]); | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * BOARD Specific: Resets audio DMA | ||
175 | */ | ||
176 | int _cx88_stop_audio_dma(snd_cx88_card_t *chip) | ||
177 | { | ||
178 | struct cx88_core *core=chip->core; | ||
179 | dprintk(1, "Stopping audio DMA\n"); | ||
180 | |||
181 | /* stop dma */ | ||
182 | cx_clear(MO_AUD_DMACNTRL, 0x11); | ||
183 | |||
184 | /* disable irqs */ | ||
185 | cx_clear(MO_PCI_INTMSK, 0x02); | ||
186 | cx_clear(MO_AUD_INTMSK, | ||
187 | (1<<16)| | ||
188 | (1<<12)| | ||
189 | (1<<4)| | ||
190 | (1<<0) | ||
191 | ); | ||
192 | |||
193 | if (debug) | ||
194 | cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]); | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | #define MAX_IRQ_LOOP 10 | ||
200 | |||
201 | /* | ||
202 | * BOARD Specific: IRQ dma bits | ||
203 | */ | ||
204 | static char *cx88_aud_irqs[32] = { | ||
205 | "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ | ||
206 | NULL, /* reserved */ | ||
207 | "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ | ||
208 | NULL, /* reserved */ | ||
209 | "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ | ||
210 | NULL, /* reserved */ | ||
211 | "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ | ||
212 | NULL, /* reserved */ | ||
213 | "opc_err", "par_err", "rip_err", /* 16-18 */ | ||
214 | "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ | ||
215 | }; | ||
216 | |||
217 | /* | ||
218 | * BOARD Specific: Threats IRQ audio specific calls | ||
219 | */ | ||
220 | static void cx8801_aud_irq(snd_cx88_card_t *chip) | ||
221 | { | ||
222 | struct cx88_core *core = chip->core; | ||
223 | u32 status, mask; | ||
224 | u32 count; | ||
225 | |||
226 | status = cx_read(MO_AUD_INTSTAT); | ||
227 | mask = cx_read(MO_AUD_INTMSK); | ||
228 | if (0 == (status & mask)) { | ||
229 | spin_unlock(&chip->reg_lock); | ||
230 | return; | ||
231 | } | ||
232 | cx_write(MO_AUD_INTSTAT, status); | ||
233 | if (debug > 1 || (status & mask & ~0xff)) | ||
234 | cx88_print_irqbits(core->name, "irq aud", | ||
235 | cx88_aud_irqs, status, mask); | ||
236 | /* risc op code error */ | ||
237 | if (status & (1 << 16)) { | ||
238 | printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name); | ||
239 | cx_clear(MO_AUD_DMACNTRL, 0x11); | ||
240 | cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]); | ||
241 | } | ||
242 | |||
243 | /* risc1 downstream */ | ||
244 | if (status & 0x01) { | ||
245 | spin_lock(&chip->reg_lock); | ||
246 | count = cx_read(MO_AUDD_GPCNT); | ||
247 | spin_unlock(&chip->reg_lock); | ||
248 | if (chip->read_count == 0) | ||
249 | chip->read_count += chip->dma_size; | ||
250 | } | ||
251 | |||
252 | if (chip->read_count >= chip->period_size) { | ||
253 | dprintk(2, "Elapsing period\n"); | ||
254 | snd_pcm_period_elapsed(chip->substream); | ||
255 | } | ||
256 | |||
257 | dprintk(3,"Leaving audio IRQ handler...\n"); | ||
258 | |||
259 | /* FIXME: Any other status should deserve a special handling? */ | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * BOARD Specific: Handles IRQ calls | ||
264 | */ | ||
265 | static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
266 | { | ||
267 | snd_cx88_card_t *chip = dev_id; | ||
268 | struct cx88_core *core = chip->core; | ||
269 | u32 status; | ||
270 | int loop, handled = 0; | ||
271 | |||
272 | for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { | ||
273 | status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02); | ||
274 | if (0 == status) | ||
275 | goto out; | ||
276 | dprintk( 3, "cx8801_irq\n" ); | ||
277 | dprintk( 3, " loop: %d/%d\n", loop, MAX_IRQ_LOOP ); | ||
278 | dprintk( 3, " status: %d\n", status ); | ||
279 | handled = 1; | ||
280 | cx_write(MO_PCI_INTSTAT, status); | ||
281 | |||
282 | if (status & 0x02) | ||
283 | { | ||
284 | dprintk( 2, " ALSA IRQ handling\n" ); | ||
285 | cx8801_aud_irq(chip); | ||
286 | } | ||
287 | }; | ||
288 | |||
289 | if (MAX_IRQ_LOOP == loop) { | ||
290 | dprintk( 0, "clearing mask\n" ); | ||
291 | dprintk(1,"%s/0: irq loop -- clearing mask\n", | ||
292 | core->name); | ||
293 | cx_clear(MO_PCI_INTMSK,0x02); | ||
294 | } | ||
295 | |||
296 | out: | ||
297 | return IRQ_RETVAL(handled); | ||
298 | } | ||
299 | |||
300 | |||
301 | static int dsp_buffer_free(snd_cx88_card_t *chip) | ||
302 | { | ||
303 | BUG_ON(!chip->dma_size); | ||
304 | |||
305 | dprintk(2,"Freeing buffer\n"); | ||
306 | videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc); | ||
307 | videobuf_dma_free(&chip->dma_risc); | ||
308 | btcx_riscmem_free(chip->pci,&chip->buf->risc); | ||
309 | kfree(chip->buf); | ||
310 | |||
311 | chip->dma_size = 0; | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | /**************************************************************************** | ||
317 | ALSA PCM Interface | ||
318 | ****************************************************************************/ | ||
319 | |||
320 | /* | ||
321 | * Digital hardware definition | ||
322 | */ | ||
323 | static snd_pcm_hardware_t snd_cx88_digital_hw = { | ||
324 | .info = SNDRV_PCM_INFO_MMAP | | ||
325 | SNDRV_PCM_INFO_INTERLEAVED | | ||
326 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
327 | SNDRV_PCM_INFO_MMAP_VALID, | ||
328 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
329 | |||
330 | .rates = SNDRV_PCM_RATE_48000, | ||
331 | .rate_min = 48000, | ||
332 | .rate_max = 48000, | ||
333 | .channels_min = 1, | ||
334 | .channels_max = 2, | ||
335 | .buffer_bytes_max = (2*2048), | ||
336 | .period_bytes_min = 256, | ||
337 | .period_bytes_max = 2048, | ||
338 | .periods_min = 2, | ||
339 | .periods_max = 16, | ||
340 | }; | ||
341 | |||
342 | /* | ||
343 | * audio pcm capture runtime free | ||
344 | */ | ||
345 | static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime) | ||
346 | { | ||
347 | } | ||
348 | /* | ||
349 | * audio pcm capture open callback | ||
350 | */ | ||
351 | static int snd_cx88_pcm_open(snd_pcm_substream_t *substream) | ||
352 | { | ||
353 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | ||
354 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
355 | int err; | ||
356 | |||
357 | if (test_and_set_bit(0, &chip->opened)) | ||
358 | return -EBUSY; | ||
359 | |||
360 | err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
361 | if (err < 0) | ||
362 | goto _error; | ||
363 | |||
364 | chip->substream = substream; | ||
365 | |||
366 | chip->read_count = 0; | ||
367 | chip->read_offset = 0; | ||
368 | |||
369 | runtime->private_free = snd_card_cx88_runtime_free; | ||
370 | runtime->hw = snd_cx88_digital_hw; | ||
371 | |||
372 | return 0; | ||
373 | _error: | ||
374 | dprintk(1,"Error opening PCM!\n"); | ||
375 | clear_bit(0, &chip->opened); | ||
376 | smp_mb__after_clear_bit(); | ||
377 | return err; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * audio close callback | ||
382 | */ | ||
383 | static int snd_cx88_close(snd_pcm_substream_t *substream) | ||
384 | { | ||
385 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | ||
386 | |||
387 | clear_bit(0, &chip->opened); | ||
388 | smp_mb__after_clear_bit(); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * hw_params callback | ||
395 | */ | ||
396 | static int snd_cx88_hw_params(snd_pcm_substream_t * substream, | ||
397 | snd_pcm_hw_params_t * hw_params) | ||
398 | { | ||
399 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | ||
400 | struct cx88_buffer *buf; | ||
401 | |||
402 | if (substream->runtime->dma_area) { | ||
403 | dsp_buffer_free(chip); | ||
404 | substream->runtime->dma_area = NULL; | ||
405 | } | ||
406 | |||
407 | |||
408 | chip->period_size = params_period_bytes(hw_params); | ||
409 | chip->num_periods = params_periods(hw_params); | ||
410 | chip->dma_size = chip->period_size * params_periods(hw_params); | ||
411 | |||
412 | BUG_ON(!chip->dma_size); | ||
413 | |||
414 | dprintk(1,"Setting buffer\n"); | ||
415 | |||
416 | buf = kmalloc(sizeof(*buf),GFP_KERNEL); | ||
417 | if (NULL == buf) | ||
418 | return -ENOMEM; | ||
419 | memset(buf,0,sizeof(*buf)); | ||
420 | |||
421 | |||
422 | buf->vb.memory = V4L2_MEMORY_MMAP; | ||
423 | buf->vb.width = chip->period_size; | ||
424 | buf->vb.height = chip->num_periods; | ||
425 | buf->vb.size = chip->dma_size; | ||
426 | buf->vb.field = V4L2_FIELD_NONE; | ||
427 | |||
428 | videobuf_dma_init(&buf->vb.dma); | ||
429 | videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE, | ||
430 | (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT)); | ||
431 | |||
432 | videobuf_dma_pci_map(chip->pci,&buf->vb.dma); | ||
433 | |||
434 | |||
435 | cx88_risc_databuffer(chip->pci, &buf->risc, | ||
436 | buf->vb.dma.sglist, | ||
437 | buf->vb.width, buf->vb.height); | ||
438 | |||
439 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | ||
440 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
441 | |||
442 | buf->vb.state = STATE_PREPARED; | ||
443 | |||
444 | buf->bpl = chip->period_size; | ||
445 | chip->buf = buf; | ||
446 | chip->dma_risc = buf->vb.dma; | ||
447 | |||
448 | dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages); | ||
449 | substream->runtime->dma_area = chip->dma_risc.vmalloc; | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | /* | ||
454 | * hw free callback | ||
455 | */ | ||
456 | static int snd_cx88_hw_free(snd_pcm_substream_t * substream) | ||
457 | { | ||
458 | |||
459 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | ||
460 | |||
461 | if (substream->runtime->dma_area) { | ||
462 | dsp_buffer_free(chip); | ||
463 | substream->runtime->dma_area = NULL; | ||
464 | } | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * prepare callback | ||
471 | */ | ||
472 | static int snd_cx88_prepare(snd_pcm_substream_t *substream) | ||
473 | { | ||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | |||
478 | /* | ||
479 | * trigger callback | ||
480 | */ | ||
481 | static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd) | ||
482 | { | ||
483 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | ||
484 | int err; | ||
485 | |||
486 | spin_lock(&chip->reg_lock); | ||
487 | |||
488 | switch (cmd) { | ||
489 | case SNDRV_PCM_TRIGGER_START: | ||
490 | err=_cx88_start_audio_dma(chip); | ||
491 | break; | ||
492 | case SNDRV_PCM_TRIGGER_STOP: | ||
493 | err=_cx88_stop_audio_dma(chip); | ||
494 | break; | ||
495 | default: | ||
496 | err=-EINVAL; | ||
497 | break; | ||
498 | } | ||
499 | |||
500 | spin_unlock(&chip->reg_lock); | ||
501 | |||
502 | return err; | ||
503 | } | ||
504 | |||
505 | /* | ||
506 | * pointer callback | ||
507 | */ | ||
508 | static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream) | ||
509 | { | ||
510 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | ||
511 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
512 | |||
513 | if (chip->read_count) { | ||
514 | chip->read_count -= snd_pcm_lib_period_bytes(substream); | ||
515 | chip->read_offset += snd_pcm_lib_period_bytes(substream); | ||
516 | if (chip->read_offset == chip->dma_size) | ||
517 | chip->read_offset = 0; | ||
518 | } | ||
519 | |||
520 | dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count); | ||
521 | return bytes_to_frames(runtime, chip->read_offset); | ||
522 | |||
523 | } | ||
524 | |||
525 | /* | ||
526 | * operators | ||
527 | */ | ||
528 | static snd_pcm_ops_t snd_cx88_pcm_ops = { | ||
529 | .open = snd_cx88_pcm_open, | ||
530 | .close = snd_cx88_close, | ||
531 | .ioctl = snd_pcm_lib_ioctl, | ||
532 | .hw_params = snd_cx88_hw_params, | ||
533 | .hw_free = snd_cx88_hw_free, | ||
534 | .prepare = snd_cx88_prepare, | ||
535 | .trigger = snd_cx88_card_trigger, | ||
536 | .pointer = snd_cx88_pointer, | ||
537 | }; | ||
538 | |||
539 | /* | ||
540 | * create a PCM device | ||
541 | */ | ||
542 | static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) | ||
543 | { | ||
544 | int err; | ||
545 | snd_pcm_t *pcm; | ||
546 | |||
547 | err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); | ||
548 | if (err < 0) | ||
549 | return err; | ||
550 | pcm->private_data = chip; | ||
551 | strcpy(pcm->name, name); | ||
552 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops); | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | /**************************************************************************** | ||
558 | CONTROL INTERFACE | ||
559 | ****************************************************************************/ | ||
560 | static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info) | ||
561 | { | ||
562 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
563 | info->count = 1; | ||
564 | info->value.integer.min = 0; | ||
565 | info->value.integer.max = 0x3f; | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | /* OK - TODO: test it */ | ||
571 | static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) | ||
572 | { | ||
573 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
574 | struct cx88_core *core=chip->core; | ||
575 | |||
576 | value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /* OK - TODO: test it */ | ||
582 | static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) | ||
583 | { | ||
584 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
585 | struct cx88_core *core=chip->core; | ||
586 | int v; | ||
587 | u32 old_control; | ||
588 | |||
589 | spin_lock_irq(&chip->reg_lock); | ||
590 | old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f); | ||
591 | v = 0x3f - (value->value.integer.value[0] & 0x3f); | ||
592 | cx_andor(AUD_VOL_CTL, 0x3f, v); | ||
593 | spin_unlock_irq(&chip->reg_lock); | ||
594 | |||
595 | return v != old_control; | ||
596 | } | ||
597 | |||
598 | static snd_kcontrol_new_t snd_cx88_capture_volume = { | ||
599 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
600 | .name = "Capture Volume", | ||
601 | .info = snd_cx88_capture_volume_info, | ||
602 | .get = snd_cx88_capture_volume_get, | ||
603 | .put = snd_cx88_capture_volume_put, | ||
604 | }; | ||
605 | |||
606 | |||
607 | /**************************************************************************** | ||
608 | Basic Flow for Sound Devices | ||
609 | ****************************************************************************/ | ||
610 | |||
611 | /* | ||
612 | * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio | ||
613 | * Only boards with eeprom and byte 1 at eeprom=1 have it | ||
614 | */ | ||
615 | |||
616 | struct pci_device_id cx88_audio_pci_tbl[] = { | ||
617 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | ||
618 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | ||
619 | {0, } | ||
620 | }; | ||
621 | MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl); | ||
622 | |||
623 | /* | ||
624 | * Chip-specific destructor | ||
625 | */ | ||
626 | |||
627 | static int snd_cx88_free(snd_cx88_card_t *chip) | ||
628 | { | ||
629 | |||
630 | if (chip->irq >= 0){ | ||
631 | synchronize_irq(chip->irq); | ||
632 | free_irq(chip->irq, chip); | ||
633 | } | ||
634 | |||
635 | cx88_core_put(chip->core,chip->pci); | ||
636 | |||
637 | pci_disable_device(chip->pci); | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | * Component Destructor | ||
643 | */ | ||
644 | static void snd_cx88_dev_free(snd_card_t * card) | ||
645 | { | ||
646 | snd_cx88_card_t *chip = card->private_data; | ||
647 | |||
648 | snd_cx88_free(chip); | ||
649 | } | ||
650 | |||
651 | |||
652 | /* | ||
653 | * Alsa Constructor - Component probe | ||
654 | */ | ||
655 | |||
656 | static int devno=0; | ||
657 | static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, | ||
658 | snd_cx88_card_t **rchip) | ||
659 | { | ||
660 | snd_cx88_card_t *chip; | ||
661 | struct cx88_core *core; | ||
662 | int err; | ||
663 | |||
664 | *rchip = NULL; | ||
665 | |||
666 | err = pci_enable_device(pci); | ||
667 | if (err < 0) | ||
668 | return err; | ||
669 | |||
670 | pci_set_master(pci); | ||
671 | |||
672 | chip = (snd_cx88_card_t *) card->private_data; | ||
673 | |||
674 | core = cx88_core_get(pci); | ||
675 | |||
676 | if (!pci_dma_supported(pci,0xffffffff)) { | ||
677 | dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); | ||
678 | err = -EIO; | ||
679 | cx88_core_put(core,pci); | ||
680 | return err; | ||
681 | } | ||
682 | |||
683 | |||
684 | /* pci init */ | ||
685 | chip->card = card; | ||
686 | chip->pci = pci; | ||
687 | chip->irq = -1; | ||
688 | spin_lock_init(&chip->reg_lock); | ||
689 | |||
690 | cx88_reset(core); | ||
691 | if (NULL == core) { | ||
692 | err = -EINVAL; | ||
693 | kfree (chip); | ||
694 | return err; | ||
695 | } | ||
696 | chip->core = core; | ||
697 | |||
698 | /* get irq */ | ||
699 | err = request_irq(chip->pci->irq, cx8801_irq, | ||
700 | SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip); | ||
701 | if (err < 0) { | ||
702 | dprintk(0, "%s: can't get IRQ %d\n", | ||
703 | chip->core->name, chip->pci->irq); | ||
704 | return err; | ||
705 | } | ||
706 | |||
707 | /* print pci info */ | ||
708 | pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev); | ||
709 | pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); | ||
710 | |||
711 | dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " | ||
712 | "latency: %d, mmio: 0x%lx\n", core->name, devno, | ||
713 | pci_name(pci), chip->pci_rev, pci->irq, | ||
714 | chip->pci_lat,pci_resource_start(pci,0)); | ||
715 | |||
716 | chip->irq = pci->irq; | ||
717 | synchronize_irq(chip->irq); | ||
718 | |||
719 | snd_card_set_dev(card, &pci->dev); | ||
720 | |||
721 | *rchip = chip; | ||
722 | |||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | static int __devinit cx88_audio_initdev(struct pci_dev *pci, | ||
727 | const struct pci_device_id *pci_id) | ||
728 | { | ||
729 | snd_card_t *card; | ||
730 | snd_cx88_card_t *chip; | ||
731 | int err; | ||
732 | |||
733 | if (devno >= SNDRV_CARDS) | ||
734 | return (-ENODEV); | ||
735 | |||
736 | if (!enable[devno]) { | ||
737 | ++devno; | ||
738 | return (-ENOENT); | ||
739 | } | ||
740 | |||
741 | card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t)); | ||
742 | if (!card) | ||
743 | return (-ENOMEM); | ||
744 | |||
745 | card->private_free = snd_cx88_dev_free; | ||
746 | |||
747 | err = snd_cx88_create(card, pci, &chip); | ||
748 | if (err < 0) | ||
749 | return (err); | ||
750 | |||
751 | err = snd_cx88_pcm(chip, 0, "CX88 Digital"); | ||
752 | |||
753 | if (err < 0) { | ||
754 | snd_card_free(card); | ||
755 | return (err); | ||
756 | } | ||
757 | |||
758 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip)); | ||
759 | if (err < 0) { | ||
760 | snd_card_free(card); | ||
761 | return (err); | ||
762 | } | ||
763 | |||
764 | strcpy (card->driver, "CX88x"); | ||
765 | sprintf(card->shortname, "Conexant CX%x", pci->device); | ||
766 | sprintf(card->longname, "%s at %#lx", | ||
767 | card->shortname, pci_resource_start(pci, 0)); | ||
768 | strcpy (card->mixername, "CX88"); | ||
769 | |||
770 | dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", | ||
771 | card->driver,devno); | ||
772 | |||
773 | err = snd_card_register(card); | ||
774 | if (err < 0) { | ||
775 | snd_card_free(card); | ||
776 | return (err); | ||
777 | } | ||
778 | snd_cx88_cards[devno] = card; | ||
779 | |||
780 | pci_set_drvdata(pci,card); | ||
781 | |||
782 | devno++; | ||
783 | return 0; | ||
784 | } | ||
785 | /* | ||
786 | * ALSA destructor | ||
787 | */ | ||
788 | static void __devexit cx88_audio_finidev(struct pci_dev *pci) | ||
789 | { | ||
790 | struct cx88_audio_dev *card = pci_get_drvdata(pci); | ||
791 | |||
792 | snd_card_free((void *)card); | ||
793 | |||
794 | pci_set_drvdata(pci, NULL); | ||
795 | |||
796 | devno--; | ||
797 | } | ||
798 | |||
799 | /* | ||
800 | * PCI driver definition | ||
801 | */ | ||
802 | |||
803 | static struct pci_driver cx88_audio_pci_driver = { | ||
804 | .name = "cx88_audio", | ||
805 | .id_table = cx88_audio_pci_tbl, | ||
806 | .probe = cx88_audio_initdev, | ||
807 | .remove = cx88_audio_finidev, | ||
808 | SND_PCI_PM_CALLBACKS | ||
809 | }; | ||
810 | |||
811 | /**************************************************************************** | ||
812 | LINUX MODULE INIT | ||
813 | ****************************************************************************/ | ||
814 | |||
815 | /* | ||
816 | * module init | ||
817 | */ | ||
818 | static int cx88_audio_init(void) | ||
819 | { | ||
820 | printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", | ||
821 | (CX88_VERSION_CODE >> 16) & 0xff, | ||
822 | (CX88_VERSION_CODE >> 8) & 0xff, | ||
823 | CX88_VERSION_CODE & 0xff); | ||
824 | #ifdef SNAPSHOT | ||
825 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", | ||
826 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | ||
827 | #endif | ||
828 | return pci_register_driver(&cx88_audio_pci_driver); | ||
829 | } | ||
830 | |||
831 | /* | ||
832 | * module remove | ||
833 | */ | ||
834 | static void cx88_audio_fini(void) | ||
835 | { | ||
836 | |||
837 | pci_unregister_driver(&cx88_audio_pci_driver); | ||
838 | } | ||
839 | |||
840 | module_init(cx88_audio_init); | ||
841 | module_exit(cx88_audio_fini); | ||
842 | |||
843 | /* ----------------------------------------------------------- */ | ||
844 | /* | ||
845 | * Local variables: | ||
846 | * c-basic-offset: 8 | ||
847 | * End: | ||
848 | */ | ||
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 74e57a53116f..a49062119313 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -32,10 +32,10 @@ | |||
32 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | 33 | ||
34 | #include "cx88.h" | 34 | #include "cx88.h" |
35 | #include <media/v4l2-common.h> | ||
35 | 36 | ||
36 | MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); | 37 | MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); |
37 | MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); | 38 | MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
38 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | ||
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | 40 | ||
41 | static unsigned int mpegbufs = 32; | 41 | static unsigned int mpegbufs = 32; |
@@ -1375,7 +1375,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
1375 | struct cx88_core *core = dev->core; | 1375 | struct cx88_core *core = dev->core; |
1376 | 1376 | ||
1377 | if (debug > 1) | 1377 | if (debug > 1) |
1378 | cx88_print_ioctl(core->name,cmd); | 1378 | v4l_print_ioctl(core->name,cmd); |
1379 | 1379 | ||
1380 | switch (cmd) { | 1380 | switch (cmd) { |
1381 | 1381 | ||
@@ -1689,6 +1689,18 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, | |||
1689 | memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); | 1689 | memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); |
1690 | memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); | 1690 | memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); |
1691 | 1691 | ||
1692 | if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) { | ||
1693 | |||
1694 | if (core->tuner_formats & V4L2_STD_525_60) { | ||
1695 | dev->height = 480; | ||
1696 | dev->params.vi_frame_rate = 30; | ||
1697 | } else { | ||
1698 | dev->height = 576; | ||
1699 | dev->params.vi_frame_rate = 25; | ||
1700 | } | ||
1701 | |||
1702 | } | ||
1703 | |||
1692 | err = cx8802_init_common(dev); | 1704 | err = cx8802_init_common(dev); |
1693 | if (0 != err) | 1705 | if (0 != err) |
1694 | goto fail_free; | 1706 | goto fail_free; |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 951709aa88ba..a76d54503b6f 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -611,12 +611,12 @@ struct cx88_board cx88_boards[] = { | |||
611 | .input = {{ | 611 | .input = {{ |
612 | .type = CX88_VMUX_TELEVISION, | 612 | .type = CX88_VMUX_TELEVISION, |
613 | .vmux = 0, | 613 | .vmux = 0, |
614 | .gpio0 = 0xed12, /* internal decoder */ | 614 | .gpio0 = 0xed1a, |
615 | .gpio2 = 0x00ff, | 615 | .gpio2 = 0x00ff, |
616 | },{ | 616 | },{ |
617 | .type = CX88_VMUX_DEBUG, | 617 | .type = CX88_VMUX_DEBUG, |
618 | .vmux = 0, | 618 | .vmux = 0, |
619 | .gpio0 = 0xff01, /* mono from tuner chip */ | 619 | .gpio0 = 0xff01, |
620 | },{ | 620 | },{ |
621 | .type = CX88_VMUX_COMPOSITE1, | 621 | .type = CX88_VMUX_COMPOSITE1, |
622 | .vmux = 1, | 622 | .vmux = 1, |
@@ -708,7 +708,7 @@ struct cx88_board cx88_boards[] = { | |||
708 | }, | 708 | }, |
709 | [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { | 709 | [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { |
710 | .name = "DViCO FusionHDTV 3 Gold-T", | 710 | .name = "DViCO FusionHDTV 3 Gold-T", |
711 | .tuner_type = TUNER_THOMSON_DTT7611, | 711 | .tuner_type = TUNER_THOMSON_DTT761X, |
712 | .radio_type = UNSET, | 712 | .radio_type = UNSET, |
713 | .tuner_addr = ADDR_UNSET, | 713 | .tuner_addr = ADDR_UNSET, |
714 | .radio_addr = ADDR_UNSET, | 714 | .radio_addr = ADDR_UNSET, |
@@ -897,6 +897,158 @@ struct cx88_board cx88_boards[] = { | |||
897 | .gpio3 = 0x0000, | 897 | .gpio3 = 0x0000, |
898 | }}, | 898 | }}, |
899 | }, | 899 | }, |
900 | [CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = { | ||
901 | .name = "Hauppauge Nova-S-Plus DVB-S", | ||
902 | .tuner_type = TUNER_ABSENT, | ||
903 | .radio_type = UNSET, | ||
904 | .tuner_addr = ADDR_UNSET, | ||
905 | .radio_addr = ADDR_UNSET, | ||
906 | .input = {{ | ||
907 | .type = CX88_VMUX_DVB, | ||
908 | .vmux = 0, | ||
909 | },{ | ||
910 | .type = CX88_VMUX_COMPOSITE1, | ||
911 | .vmux = 1, | ||
912 | },{ | ||
913 | .type = CX88_VMUX_SVIDEO, | ||
914 | .vmux = 2, | ||
915 | }}, | ||
916 | .dvb = 1, | ||
917 | }, | ||
918 | [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = { | ||
919 | .name = "Hauppauge Nova-SE2 DVB-S", | ||
920 | .tuner_type = TUNER_ABSENT, | ||
921 | .radio_type = UNSET, | ||
922 | .tuner_addr = ADDR_UNSET, | ||
923 | .radio_addr = ADDR_UNSET, | ||
924 | .input = {{ | ||
925 | .type = CX88_VMUX_DVB, | ||
926 | .vmux = 0, | ||
927 | }}, | ||
928 | .dvb = 1, | ||
929 | }, | ||
930 | [CX88_BOARD_KWORLD_DVBS_100] = { | ||
931 | .name = "KWorld DVB-S 100", | ||
932 | .tuner_type = TUNER_ABSENT, | ||
933 | .radio_type = UNSET, | ||
934 | .tuner_addr = ADDR_UNSET, | ||
935 | .radio_addr = ADDR_UNSET, | ||
936 | .input = {{ | ||
937 | .type = CX88_VMUX_DVB, | ||
938 | .vmux = 0, | ||
939 | },{ | ||
940 | .type = CX88_VMUX_COMPOSITE1, | ||
941 | .vmux = 1, | ||
942 | },{ | ||
943 | .type = CX88_VMUX_SVIDEO, | ||
944 | .vmux = 2, | ||
945 | }}, | ||
946 | .dvb = 1, | ||
947 | }, | ||
948 | [CX88_BOARD_HAUPPAUGE_HVR1100] = { | ||
949 | .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid", | ||
950 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, | ||
951 | .radio_type = UNSET, | ||
952 | .tuner_addr = ADDR_UNSET, | ||
953 | .radio_addr = ADDR_UNSET, | ||
954 | .tda9887_conf = TDA9887_PRESENT, | ||
955 | .input = {{ | ||
956 | .type = CX88_VMUX_TELEVISION, | ||
957 | .vmux = 0, | ||
958 | },{ | ||
959 | .type = CX88_VMUX_COMPOSITE1, | ||
960 | .vmux = 1, | ||
961 | },{ | ||
962 | .type = CX88_VMUX_SVIDEO, | ||
963 | .vmux = 2, | ||
964 | }}, | ||
965 | /* fixme: Add radio support */ | ||
966 | .dvb = 1, | ||
967 | }, | ||
968 | [CX88_BOARD_HAUPPAUGE_HVR1100LP] = { | ||
969 | .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)", | ||
970 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, | ||
971 | .radio_type = UNSET, | ||
972 | .tuner_addr = ADDR_UNSET, | ||
973 | .radio_addr = ADDR_UNSET, | ||
974 | .tda9887_conf = TDA9887_PRESENT, | ||
975 | .input = {{ | ||
976 | .type = CX88_VMUX_TELEVISION, | ||
977 | .vmux = 0, | ||
978 | },{ | ||
979 | .type = CX88_VMUX_COMPOSITE1, | ||
980 | .vmux = 1, | ||
981 | }}, | ||
982 | /* fixme: Add radio support */ | ||
983 | .dvb = 1, | ||
984 | }, | ||
985 | [CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = { | ||
986 | .name = "digitalnow DNTV Live! DVB-T Pro", | ||
987 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, | ||
988 | .radio_type = UNSET, | ||
989 | .tuner_addr = ADDR_UNSET, | ||
990 | .radio_addr = ADDR_UNSET, | ||
991 | .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | | ||
992 | TDA9887_PORT2_ACTIVE, | ||
993 | .input = {{ | ||
994 | .type = CX88_VMUX_TELEVISION, | ||
995 | .vmux = 0, | ||
996 | .gpio0 = 0xf80808, | ||
997 | },{ | ||
998 | .type = CX88_VMUX_COMPOSITE1, | ||
999 | .vmux = 1, | ||
1000 | .gpio0 = 0xf80808, | ||
1001 | },{ | ||
1002 | .type = CX88_VMUX_SVIDEO, | ||
1003 | .vmux = 2, | ||
1004 | .gpio0 = 0xf80808, | ||
1005 | }}, | ||
1006 | .radio = { | ||
1007 | .type = CX88_RADIO, | ||
1008 | .gpio0 = 0xf80808, | ||
1009 | }, | ||
1010 | .dvb = 1, | ||
1011 | }, | ||
1012 | [CX88_BOARD_KWORLD_DVB_T_CX22702] = { | ||
1013 | /* Kworld V-stream Xpert DVB-T with Thomson tuner */ | ||
1014 | /* DTT 7579 Conexant CX22702-19 Conexant CX2388x */ | ||
1015 | /* Manenti Marco <marco_manenti@colman.it> */ | ||
1016 | .name = "KWorld/VStream XPert DVB-T with cx22702", | ||
1017 | .tuner_type = TUNER_ABSENT, | ||
1018 | .radio_type = UNSET, | ||
1019 | .tuner_addr = ADDR_UNSET, | ||
1020 | .radio_addr = ADDR_UNSET, | ||
1021 | .input = {{ | ||
1022 | .type = CX88_VMUX_COMPOSITE1, | ||
1023 | .vmux = 1, | ||
1024 | .gpio0 = 0x0700, | ||
1025 | .gpio2 = 0x0101, | ||
1026 | },{ | ||
1027 | .type = CX88_VMUX_SVIDEO, | ||
1028 | .vmux = 2, | ||
1029 | .gpio0 = 0x0700, | ||
1030 | .gpio2 = 0x0101, | ||
1031 | }}, | ||
1032 | .dvb = 1, | ||
1033 | }, | ||
1034 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = { | ||
1035 | .name = "DViCO FusionHDTV DVB-T Dual Digital", | ||
1036 | .tuner_type = TUNER_ABSENT, /* No analog tuner */ | ||
1037 | .radio_type = UNSET, | ||
1038 | .tuner_addr = ADDR_UNSET, | ||
1039 | .radio_addr = ADDR_UNSET, | ||
1040 | .input = {{ | ||
1041 | .type = CX88_VMUX_COMPOSITE1, | ||
1042 | .vmux = 1, | ||
1043 | .gpio0 = 0x000027df, | ||
1044 | },{ | ||
1045 | .type = CX88_VMUX_SVIDEO, | ||
1046 | .vmux = 2, | ||
1047 | .gpio0 = 0x000027df, | ||
1048 | }}, | ||
1049 | .dvb = 1, | ||
1050 | }, | ||
1051 | |||
900 | }; | 1052 | }; |
901 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 1053 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
902 | 1054 | ||
@@ -1044,6 +1196,54 @@ struct cx88_subid cx88_subids[] = { | |||
1044 | .subvendor = 0x1461, | 1196 | .subvendor = 0x1461, |
1045 | .subdevice = 0x000a, | 1197 | .subdevice = 0x000a, |
1046 | .card = CX88_BOARD_AVERTV_303, | 1198 | .card = CX88_BOARD_AVERTV_303, |
1199 | },{ | ||
1200 | .subvendor = 0x0070, | ||
1201 | .subdevice = 0x9200, | ||
1202 | .card = CX88_BOARD_HAUPPAUGE_NOVASE2_S1, | ||
1203 | },{ | ||
1204 | .subvendor = 0x0070, | ||
1205 | .subdevice = 0x9201, | ||
1206 | .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1, | ||
1207 | },{ | ||
1208 | .subvendor = 0x0070, | ||
1209 | .subdevice = 0x9202, | ||
1210 | .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1, | ||
1211 | },{ | ||
1212 | .subvendor = 0x17de, | ||
1213 | .subdevice = 0x08b2, | ||
1214 | .card = CX88_BOARD_KWORLD_DVBS_100, | ||
1215 | },{ | ||
1216 | .subvendor = 0x0070, | ||
1217 | .subdevice = 0x9400, | ||
1218 | .card = CX88_BOARD_HAUPPAUGE_HVR1100, | ||
1219 | },{ | ||
1220 | .subvendor = 0x0070, | ||
1221 | .subdevice = 0x9402, | ||
1222 | .card = CX88_BOARD_HAUPPAUGE_HVR1100, | ||
1223 | },{ | ||
1224 | .subvendor = 0x0070, | ||
1225 | .subdevice = 0x9800, | ||
1226 | .card = CX88_BOARD_HAUPPAUGE_HVR1100LP, | ||
1227 | },{ | ||
1228 | .subvendor = 0x0070, | ||
1229 | .subdevice = 0x9802, | ||
1230 | .card = CX88_BOARD_HAUPPAUGE_HVR1100LP, | ||
1231 | },{ | ||
1232 | .subvendor = 0x0070, | ||
1233 | .subdevice = 0x9001, | ||
1234 | .card = CX88_BOARD_HAUPPAUGE_DVB_T1, | ||
1235 | },{ | ||
1236 | .subvendor = 0x1822, | ||
1237 | .subdevice = 0x0025, | ||
1238 | .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO, | ||
1239 | },{ | ||
1240 | .subvendor = 0x17de, | ||
1241 | .subdevice = 0x08a1, | ||
1242 | .card = CX88_BOARD_KWORLD_DVB_T_CX22702, | ||
1243 | },{ | ||
1244 | .subvendor = 0x18ac, | ||
1245 | .subdevice = 0xdb50, | ||
1246 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, | ||
1047 | }, | 1247 | }, |
1048 | }; | 1248 | }; |
1049 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 1249 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
@@ -1075,20 +1275,19 @@ static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1075 | core->name, core->tuner_type, eeprom_data[0]); | 1275 | core->name, core->tuner_type, eeprom_data[0]); |
1076 | } | 1276 | } |
1077 | 1277 | ||
1078 | |||
1079 | /* ----------------------------------------------------------------------- */ | ||
1080 | |||
1081 | static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | 1278 | static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) |
1082 | { | 1279 | { |
1083 | struct tveeprom tv; | 1280 | struct tveeprom tv; |
1084 | 1281 | ||
1085 | tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); | 1282 | tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); |
1086 | core->tuner_type = tv.tuner_type; | 1283 | core->tuner_type = tv.tuner_type; |
1284 | core->tuner_formats = tv.tuner_formats; | ||
1087 | core->has_radio = tv.has_radio; | 1285 | core->has_radio = tv.has_radio; |
1088 | 1286 | ||
1089 | /* Make sure we support the board model */ | 1287 | /* Make sure we support the board model */ |
1090 | switch (tv.model) | 1288 | switch (tv.model) |
1091 | { | 1289 | { |
1290 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ | ||
1092 | case 90002: /* Nova-T-PCI (9002) */ | 1291 | case 90002: /* Nova-T-PCI (9002) */ |
1093 | case 92001: /* Nova-S-Plus (Video and IR) */ | 1292 | case 92001: /* Nova-S-Plus (Video and IR) */ |
1094 | case 92002: /* Nova-S-Plus (Video and IR) */ | 1293 | case 92002: /* Nova-S-Plus (Video and IR) */ |
@@ -1096,7 +1295,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1096 | case 90500: /* Nova-T-PCI (oem) */ | 1295 | case 90500: /* Nova-T-PCI (oem) */ |
1097 | case 90501: /* Nova-T-PCI (oem/IR) */ | 1296 | case 90501: /* Nova-T-PCI (oem/IR) */ |
1098 | case 92000: /* Nova-SE2 (OEM, No Video or IR) */ | 1297 | case 92000: /* Nova-SE2 (OEM, No Video or IR) */ |
1099 | 1298 | case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ | |
1299 | case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ | ||
1300 | case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */ | ||
1100 | /* known */ | 1301 | /* known */ |
1101 | break; | 1302 | break; |
1102 | default: | 1303 | default: |
@@ -1211,12 +1412,21 @@ void cx88_card_setup(struct cx88_core *core) | |||
1211 | if (0 == core->i2c_rc) | 1412 | if (0 == core->i2c_rc) |
1212 | leadtek_eeprom(core,eeprom); | 1413 | leadtek_eeprom(core,eeprom); |
1213 | break; | 1414 | break; |
1415 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
1416 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
1214 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 1417 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
1418 | case CX88_BOARD_HAUPPAUGE_HVR1100: | ||
1419 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | ||
1215 | if (0 == core->i2c_rc) | 1420 | if (0 == core->i2c_rc) |
1216 | hauppauge_eeprom(core,eeprom); | 1421 | hauppauge_eeprom(core,eeprom); |
1217 | break; | 1422 | break; |
1423 | case CX88_BOARD_KWORLD_DVBS_100: | ||
1424 | cx_write(MO_GP0_IO, 0x000007f8); | ||
1425 | cx_write(MO_GP1_IO, 0x00000001); | ||
1426 | break; | ||
1218 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 1427 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
1219 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 1428 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
1429 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | ||
1220 | /* GPIO0:0 is hooked to mt352 reset pin */ | 1430 | /* GPIO0:0 is hooked to mt352 reset pin */ |
1221 | cx_set(MO_GP0_IO, 0x00000101); | 1431 | cx_set(MO_GP0_IO, 0x00000101); |
1222 | cx_clear(MO_GP0_IO, 0x00000001); | 1432 | cx_clear(MO_GP0_IO, 0x00000001); |
@@ -1232,6 +1442,9 @@ void cx88_card_setup(struct cx88_core *core) | |||
1232 | cx_clear(MO_GP0_IO, 0x00000007); | 1442 | cx_clear(MO_GP0_IO, 0x00000007); |
1233 | cx_set(MO_GP2_IO, 0x00000101); | 1443 | cx_set(MO_GP2_IO, 0x00000101); |
1234 | break; | 1444 | break; |
1445 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | ||
1446 | cx_write(MO_GP0_IO, 0x00080808); | ||
1447 | break; | ||
1235 | case CX88_BOARD_ATI_HDTVWONDER: | 1448 | case CX88_BOARD_ATI_HDTVWONDER: |
1236 | if (0 == core->i2c_rc) { | 1449 | if (0 == core->i2c_rc) { |
1237 | /* enable tuner */ | 1450 | /* enable tuner */ |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index bb6eb54e19ce..9975be1aca38 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
35 | 35 | ||
36 | #include "cx88.h" | 36 | #include "cx88.h" |
37 | #include <media/v4l2-common.h> | ||
37 | 38 | ||
38 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); | 39 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); |
39 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 40 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
@@ -76,60 +77,6 @@ static unsigned int cx88_devcount; | |||
76 | static LIST_HEAD(cx88_devlist); | 77 | static LIST_HEAD(cx88_devlist); |
77 | static DECLARE_MUTEX(devlist); | 78 | static DECLARE_MUTEX(devlist); |
78 | 79 | ||
79 | /* ------------------------------------------------------------------ */ | ||
80 | /* debug help functions */ | ||
81 | |||
82 | static const char *v4l1_ioctls[] = { | ||
83 | "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", | ||
84 | "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", | ||
85 | "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", | ||
86 | "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", | ||
87 | "SMICROCODE", "GVBIFMT", "SVBIFMT" }; | ||
88 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
89 | |||
90 | static const char *v4l2_ioctls[] = { | ||
91 | "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", | ||
92 | "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", | ||
93 | "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", | ||
94 | "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", | ||
95 | "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", | ||
96 | "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", | ||
97 | "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", | ||
98 | "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", | ||
99 | "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", | ||
100 | "S_MODULATOR" | ||
101 | }; | ||
102 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | ||
103 | |||
104 | void cx88_print_ioctl(char *name, unsigned int cmd) | ||
105 | { | ||
106 | char *dir; | ||
107 | |||
108 | switch (_IOC_DIR(cmd)) { | ||
109 | case _IOC_NONE: dir = "--"; break; | ||
110 | case _IOC_READ: dir = "r-"; break; | ||
111 | case _IOC_WRITE: dir = "-w"; break; | ||
112 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
113 | default: dir = "??"; break; | ||
114 | } | ||
115 | switch (_IOC_TYPE(cmd)) { | ||
116 | case 'v': | ||
117 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", | ||
118 | name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? | ||
119 | v4l1_ioctls[_IOC_NR(cmd)] : "???"); | ||
120 | break; | ||
121 | case 'V': | ||
122 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", | ||
123 | name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? | ||
124 | v4l2_ioctls[_IOC_NR(cmd)] : "???"); | ||
125 | break; | ||
126 | default: | ||
127 | printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", | ||
128 | name, cmd, dir, _IOC_NR(cmd)); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* ------------------------------------------------------------------ */ | ||
133 | #define NO_SYNC_LINE (-1U) | 80 | #define NO_SYNC_LINE (-1U) |
134 | 81 | ||
135 | static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, | 82 | static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, |
@@ -291,9 +238,9 @@ cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) | |||
291 | * channel 22 (u video) - 2.0k | 238 | * channel 22 (u video) - 2.0k |
292 | * channel 23 (v video) - 2.0k | 239 | * channel 23 (v video) - 2.0k |
293 | * channel 24 (vbi) - 4.0k | 240 | * channel 24 (vbi) - 4.0k |
294 | * channels 25+26 (audio) - 0.5k | 241 | * channels 25+26 (audio) - 4.0k |
295 | * channel 28 (mpeg) - 4.0k | 242 | * channel 28 (mpeg) - 4.0k |
296 | * TOTAL = 25.5k | 243 | * TOTAL = 29.0k |
297 | * | 244 | * |
298 | * Every channel has 160 bytes control data (64 bytes instruction | 245 | * Every channel has 160 bytes control data (64 bytes instruction |
299 | * queue and 6 CDT entries), which is close to 2k total. | 246 | * queue and 6 CDT entries), which is close to 2k total. |
@@ -359,7 +306,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
359 | .ctrl_start = 0x180680, | 306 | .ctrl_start = 0x180680, |
360 | .cdt = 0x180680 + 64, | 307 | .cdt = 0x180680 + 64, |
361 | .fifo_start = 0x185400, | 308 | .fifo_start = 0x185400, |
362 | .fifo_size = 0x000200, | 309 | .fifo_size = 0x001000, |
363 | .ptr1_reg = MO_DMA25_PTR1, | 310 | .ptr1_reg = MO_DMA25_PTR1, |
364 | .ptr2_reg = MO_DMA25_PTR2, | 311 | .ptr2_reg = MO_DMA25_PTR2, |
365 | .cnt1_reg = MO_DMA25_CNT1, | 312 | .cnt1_reg = MO_DMA25_CNT1, |
@@ -371,7 +318,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
371 | .ctrl_start = 0x180720, | 318 | .ctrl_start = 0x180720, |
372 | .cdt = 0x180680 + 64, /* same as audio IN */ | 319 | .cdt = 0x180680 + 64, /* same as audio IN */ |
373 | .fifo_start = 0x185400, /* same as audio IN */ | 320 | .fifo_start = 0x185400, /* same as audio IN */ |
374 | .fifo_size = 0x000200, /* same as audio IN */ | 321 | .fifo_size = 0x001000, /* same as audio IN */ |
375 | .ptr1_reg = MO_DMA26_PTR1, | 322 | .ptr1_reg = MO_DMA26_PTR1, |
376 | .ptr2_reg = MO_DMA26_PTR2, | 323 | .ptr2_reg = MO_DMA26_PTR2, |
377 | .cnt1_reg = MO_DMA26_CNT1, | 324 | .cnt1_reg = MO_DMA26_CNT1, |
@@ -382,7 +329,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
382 | .cmds_start = 0x180200, | 329 | .cmds_start = 0x180200, |
383 | .ctrl_start = 0x1807C0, | 330 | .ctrl_start = 0x1807C0, |
384 | .cdt = 0x1807C0 + 64, | 331 | .cdt = 0x1807C0 + 64, |
385 | .fifo_start = 0x185600, | 332 | .fifo_start = 0x186400, |
386 | .fifo_size = 0x001000, | 333 | .fifo_size = 0x001000, |
387 | .ptr1_reg = MO_DMA28_PTR1, | 334 | .ptr1_reg = MO_DMA28_PTR1, |
388 | .ptr2_reg = MO_DMA28_PTR2, | 335 | .ptr2_reg = MO_DMA28_PTR2, |
@@ -848,7 +795,6 @@ int cx88_start_audio_dma(struct cx88_core *core) | |||
848 | 795 | ||
849 | /* start dma */ | 796 | /* start dma */ |
850 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ | 797 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ |
851 | |||
852 | return 0; | 798 | return 0; |
853 | } | 799 | } |
854 | 800 | ||
@@ -1208,7 +1154,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) | |||
1208 | 1154 | ||
1209 | /* ------------------------------------------------------------------ */ | 1155 | /* ------------------------------------------------------------------ */ |
1210 | 1156 | ||
1211 | EXPORT_SYMBOL(cx88_print_ioctl); | ||
1212 | EXPORT_SYMBOL(cx88_print_irqbits); | 1157 | EXPORT_SYMBOL(cx88_print_irqbits); |
1213 | 1158 | ||
1214 | EXPORT_SYMBOL(cx88_core_irq); | 1159 | EXPORT_SYMBOL(cx88_core_irq); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 99ea955f5987..42c012aaa849 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * device driver for Conexant 2388x based TV cards | 3 | * device driver for Conexant 2388x based TV cards |
4 | * MPEG Transport Stream (DVB) routines | 4 | * MPEG Transport Stream (DVB) routines |
5 | * | 5 | * |
6 | * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> | 6 | * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> |
7 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 7 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -31,10 +31,14 @@ | |||
31 | 31 | ||
32 | #include "cx88.h" | 32 | #include "cx88.h" |
33 | #include "dvb-pll.h" | 33 | #include "dvb-pll.h" |
34 | #include <media/v4l2-common.h> | ||
34 | 35 | ||
35 | #ifdef HAVE_MT352 | 36 | #ifdef HAVE_MT352 |
36 | # include "mt352.h" | 37 | # include "mt352.h" |
37 | # include "mt352_priv.h" | 38 | # include "mt352_priv.h" |
39 | # ifdef HAVE_VP3054_I2C | ||
40 | # include "cx88-vp3054-i2c.h" | ||
41 | # endif | ||
38 | #endif | 42 | #endif |
39 | #ifdef HAVE_CX22702 | 43 | #ifdef HAVE_CX22702 |
40 | # include "cx22702.h" | 44 | # include "cx22702.h" |
@@ -48,6 +52,9 @@ | |||
48 | #ifdef HAVE_NXT200X | 52 | #ifdef HAVE_NXT200X |
49 | # include "nxt200x.h" | 53 | # include "nxt200x.h" |
50 | #endif | 54 | #endif |
55 | #ifdef HAVE_CX24123 | ||
56 | # include "cx24123.h" | ||
57 | #endif | ||
51 | 58 | ||
52 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 59 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
53 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 60 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
@@ -125,6 +132,27 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | |||
125 | return 0; | 132 | return 0; |
126 | } | 133 | } |
127 | 134 | ||
135 | static int dvico_dual_demod_init(struct dvb_frontend *fe) | ||
136 | { | ||
137 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | ||
138 | static u8 reset [] = { RESET, 0x80 }; | ||
139 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | ||
140 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | ||
141 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | ||
142 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
143 | |||
144 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
145 | udelay(200); | ||
146 | mt352_write(fe, reset, sizeof(reset)); | ||
147 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
148 | |||
149 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
150 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | ||
151 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
128 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | 156 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) |
129 | { | 157 | { |
130 | static u8 clock_config [] = { 0x89, 0x38, 0x39 }; | 158 | static u8 clock_config [] = { 0x89, 0x38, 0x39 }; |
@@ -172,6 +200,98 @@ static struct mt352_config dntv_live_dvbt_config = { | |||
172 | .demod_init = dntv_live_dvbt_demod_init, | 200 | .demod_init = dntv_live_dvbt_demod_init, |
173 | .pll_set = mt352_pll_set, | 201 | .pll_set = mt352_pll_set, |
174 | }; | 202 | }; |
203 | |||
204 | static struct mt352_config dvico_fusionhdtv_dual = { | ||
205 | .demod_address = 0x0F, | ||
206 | .demod_init = dvico_dual_demod_init, | ||
207 | .pll_set = mt352_pll_set, | ||
208 | }; | ||
209 | |||
210 | #ifdef HAVE_VP3054_I2C | ||
211 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) | ||
212 | { | ||
213 | static u8 clock_config [] = { 0x89, 0x38, 0x38 }; | ||
214 | static u8 reset [] = { 0x50, 0x80 }; | ||
215 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
216 | static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, | ||
217 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | ||
218 | static u8 dntv_extra[] = { 0xB5, 0x7A }; | ||
219 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | ||
220 | |||
221 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
222 | udelay(2000); | ||
223 | mt352_write(fe, reset, sizeof(reset)); | ||
224 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
225 | |||
226 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
227 | udelay(2000); | ||
228 | mt352_write(fe, dntv_extra, sizeof(dntv_extra)); | ||
229 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | ||
235 | { | ||
236 | struct cx8802_dev *dev= fe->dvb->priv; | ||
237 | |||
238 | /* this message is to set up ATC and ALC */ | ||
239 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | ||
240 | struct i2c_msg msg = | ||
241 | { .addr = dev->core->pll_addr, .flags = 0, | ||
242 | .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; | ||
243 | int err; | ||
244 | |||
245 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | else | ||
249 | return -EREMOTEIO; | ||
250 | } | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, | ||
256 | struct dvb_frontend_parameters* params, | ||
257 | u8* pllbuf) | ||
258 | { | ||
259 | struct cx8802_dev *dev= fe->dvb->priv; | ||
260 | struct i2c_msg msg = | ||
261 | { .addr = dev->core->pll_addr, .flags = 0, | ||
262 | .buf = pllbuf+1, .len = 4 }; | ||
263 | int err; | ||
264 | |||
265 | /* Switch PLL to DVB mode */ | ||
266 | err = philips_fmd1216_pll_init(fe); | ||
267 | if (err) | ||
268 | return err; | ||
269 | |||
270 | /* Tune PLL */ | ||
271 | pllbuf[0] = dev->core->pll_addr << 1; | ||
272 | dvb_pll_configure(dev->core->pll_desc, pllbuf+1, | ||
273 | params->frequency, | ||
274 | params->u.ofdm.bandwidth); | ||
275 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
276 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
277 | "(addr %02x <- %02x, err = %i)\n", | ||
278 | __FUNCTION__, pllbuf[0], pllbuf[1], err); | ||
279 | if (err < 0) | ||
280 | return err; | ||
281 | else | ||
282 | return -EREMOTEIO; | ||
283 | } | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static struct mt352_config dntv_live_dvbt_pro_config = { | ||
289 | .demod_address = 0x0f, | ||
290 | .no_tuner = 1, | ||
291 | .demod_init = dntv_live_dvbt_pro_demod_init, | ||
292 | .pll_set = dntv_live_dvbt_pro_pll_set, | ||
293 | }; | ||
294 | #endif | ||
175 | #endif | 295 | #endif |
176 | 296 | ||
177 | #ifdef HAVE_CX22702 | 297 | #ifdef HAVE_CX22702 |
@@ -188,6 +308,12 @@ static struct cx22702_config hauppauge_novat_config = { | |||
188 | .pll_address = 0x61, | 308 | .pll_address = 0x61, |
189 | .pll_desc = &dvb_pll_thomson_dtt759x, | 309 | .pll_desc = &dvb_pll_thomson_dtt759x, |
190 | }; | 310 | }; |
311 | static struct cx22702_config hauppauge_hvr1100_config = { | ||
312 | .demod_address = 0x63, | ||
313 | .output_mode = CX22702_SERIAL_OUTPUT, | ||
314 | .pll_address = 0x61, | ||
315 | .pll_desc = &dvb_pll_fmd1216me, | ||
316 | }; | ||
191 | #endif | 317 | #endif |
192 | 318 | ||
193 | #ifdef HAVE_OR51132 | 319 | #ifdef HAVE_OR51132 |
@@ -314,6 +440,40 @@ static struct nxt200x_config ati_hdtvwonder = { | |||
314 | }; | 440 | }; |
315 | #endif | 441 | #endif |
316 | 442 | ||
443 | #ifdef HAVE_CX24123 | ||
444 | static int cx24123_set_ts_param(struct dvb_frontend* fe, | ||
445 | int is_punctured) | ||
446 | { | ||
447 | struct cx8802_dev *dev= fe->dvb->priv; | ||
448 | dev->ts_gen_cntrl = 0x2; | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) | ||
453 | { | ||
454 | struct cx8802_dev *dev= fe->dvb->priv; | ||
455 | struct cx88_core *core = dev->core; | ||
456 | |||
457 | if (on) | ||
458 | cx_write(MO_GP0_IO, 0x000006f9); | ||
459 | else | ||
460 | cx_write(MO_GP0_IO, 0x000006fB); | ||
461 | } | ||
462 | |||
463 | static struct cx24123_config hauppauge_novas_config = { | ||
464 | .demod_address = 0x55, | ||
465 | .use_isl6421 = 1, | ||
466 | .set_ts_params = cx24123_set_ts_param, | ||
467 | }; | ||
468 | |||
469 | static struct cx24123_config kworld_dvbs_100_config = { | ||
470 | .demod_address = 0x15, | ||
471 | .use_isl6421 = 0, | ||
472 | .set_ts_params = cx24123_set_ts_param, | ||
473 | .enable_lnb_voltage = cx24123_enable_lnb_voltage, | ||
474 | }; | ||
475 | #endif | ||
476 | |||
317 | static int dvb_register(struct cx8802_dev *dev) | 477 | static int dvb_register(struct cx8802_dev *dev) |
318 | { | 478 | { |
319 | /* init struct videobuf_dvb */ | 479 | /* init struct videobuf_dvb */ |
@@ -329,10 +489,16 @@ static int dvb_register(struct cx8802_dev *dev) | |||
329 | break; | 489 | break; |
330 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 490 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
331 | case CX88_BOARD_CONEXANT_DVB_T1: | 491 | case CX88_BOARD_CONEXANT_DVB_T1: |
492 | case CX88_BOARD_KWORLD_DVB_T_CX22702: | ||
332 | case CX88_BOARD_WINFAST_DTV1000: | 493 | case CX88_BOARD_WINFAST_DTV1000: |
333 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, | 494 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, |
334 | &dev->core->i2c_adap); | 495 | &dev->core->i2c_adap); |
335 | break; | 496 | break; |
497 | case CX88_BOARD_HAUPPAUGE_HVR1100: | ||
498 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | ||
499 | dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, | ||
500 | &dev->core->i2c_adap); | ||
501 | break; | ||
336 | #endif | 502 | #endif |
337 | #ifdef HAVE_MT352 | 503 | #ifdef HAVE_MT352 |
338 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 504 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
@@ -355,6 +521,24 @@ static int dvb_register(struct cx8802_dev *dev) | |||
355 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, | 521 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, |
356 | &dev->core->i2c_adap); | 522 | &dev->core->i2c_adap); |
357 | break; | 523 | break; |
524 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | ||
525 | #ifdef HAVE_VP3054_I2C | ||
526 | dev->core->pll_addr = 0x61; | ||
527 | dev->core->pll_desc = &dvb_pll_fmd1216me; | ||
528 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, | ||
529 | &((struct vp3054_i2c_state *)dev->card_priv)->adap); | ||
530 | #else | ||
531 | printk("%s: built without vp3054 support\n", dev->core->name); | ||
532 | #endif | ||
533 | break; | ||
534 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | ||
535 | /* The tin box says DEE1601, but it seems to be DTT7579 | ||
536 | * compatible, with a slightly different MT352 AGC gain. */ | ||
537 | dev->core->pll_addr = 0x61; | ||
538 | dev->core->pll_desc = &dvb_pll_thomson_dtt7579; | ||
539 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, | ||
540 | &dev->core->i2c_adap); | ||
541 | break; | ||
358 | #endif | 542 | #endif |
359 | #ifdef HAVE_OR51132 | 543 | #ifdef HAVE_OR51132 |
360 | case CX88_BOARD_PCHDTV_HD3000: | 544 | case CX88_BOARD_PCHDTV_HD3000: |
@@ -393,7 +577,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
393 | cx_set(MO_GP0_IO, 9); | 577 | cx_set(MO_GP0_IO, 9); |
394 | mdelay(200); | 578 | mdelay(200); |
395 | dev->core->pll_addr = 0x61; | 579 | dev->core->pll_addr = 0x61; |
396 | dev->core->pll_desc = &dvb_pll_thomson_dtt7611; | 580 | dev->core->pll_desc = &dvb_pll_thomson_dtt761x; |
397 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, | 581 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, |
398 | &dev->core->i2c_adap); | 582 | &dev->core->i2c_adap); |
399 | } | 583 | } |
@@ -421,6 +605,17 @@ static int dvb_register(struct cx8802_dev *dev) | |||
421 | &dev->core->i2c_adap); | 605 | &dev->core->i2c_adap); |
422 | break; | 606 | break; |
423 | #endif | 607 | #endif |
608 | #ifdef HAVE_CX24123 | ||
609 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
610 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
611 | dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, | ||
612 | &dev->core->i2c_adap); | ||
613 | break; | ||
614 | case CX88_BOARD_KWORLD_DVBS_100: | ||
615 | dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, | ||
616 | &dev->core->i2c_adap); | ||
617 | break; | ||
618 | #endif | ||
424 | default: | 619 | default: |
425 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 620 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
426 | dev->core->name); | 621 | dev->core->name); |
@@ -473,6 +668,12 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
473 | if (0 != err) | 668 | if (0 != err) |
474 | goto fail_free; | 669 | goto fail_free; |
475 | 670 | ||
671 | #ifdef HAVE_VP3054_I2C | ||
672 | err = vp3054_i2c_probe(dev); | ||
673 | if (0 != err) | ||
674 | goto fail_free; | ||
675 | #endif | ||
676 | |||
476 | /* dvb stuff */ | 677 | /* dvb stuff */ |
477 | printk("%s/2: cx2388x based dvb card\n", core->name); | 678 | printk("%s/2: cx2388x based dvb card\n", core->name); |
478 | videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, | 679 | videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, |
@@ -484,6 +685,9 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
484 | err = dvb_register(dev); | 685 | err = dvb_register(dev); |
485 | if (0 != err) | 686 | if (0 != err) |
486 | goto fail_fini; | 687 | goto fail_fini; |
688 | |||
689 | /* Maintain a reference to cx88-video can query the 8802 device. */ | ||
690 | core->dvbdev = dev; | ||
487 | return 0; | 691 | return 0; |
488 | 692 | ||
489 | fail_fini: | 693 | fail_fini: |
@@ -499,9 +703,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev) | |||
499 | { | 703 | { |
500 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | 704 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); |
501 | 705 | ||
706 | /* Destroy any 8802 reference. */ | ||
707 | dev->core->dvbdev = NULL; | ||
708 | |||
502 | /* dvb */ | 709 | /* dvb */ |
503 | videobuf_dvb_unregister(&dev->dvb); | 710 | videobuf_dvb_unregister(&dev->dvb); |
504 | 711 | ||
712 | #ifdef HAVE_VP3054_I2C | ||
713 | vp3054_i2c_remove(dev); | ||
714 | #endif | ||
715 | |||
505 | /* common */ | 716 | /* common */ |
506 | cx8802_fini_common(dev); | 717 | cx8802_fini_common(dev); |
507 | cx88_core_put(dev->core,dev->pci); | 718 | cx88_core_put(dev->core,dev->pci); |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 4a8fb161b16a..f720901e9638 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | 31 | ||
32 | #include "cx88.h" | 32 | #include "cx88.h" |
33 | #include <media/v4l2-common.h> | ||
33 | 34 | ||
34 | static unsigned int i2c_debug = 0; | 35 | static unsigned int i2c_debug = 0; |
35 | module_param(i2c_debug, int, 0644); | 36 | module_param(i2c_debug, int, 0644); |
@@ -135,7 +136,17 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) | |||
135 | { | 136 | { |
136 | if (0 != core->i2c_rc) | 137 | if (0 != core->i2c_rc) |
137 | return; | 138 | return; |
138 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 139 | |
140 | if (core->dvbdev) { | ||
141 | if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) | ||
142 | core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); | ||
143 | |||
144 | i2c_clients_command(&core->i2c_adap, cmd, arg); | ||
145 | |||
146 | if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) | ||
147 | core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); | ||
148 | } else | ||
149 | i2c_clients_command(&core->i2c_adap, cmd, arg); | ||
139 | } | 150 | } |
140 | 151 | ||
141 | static struct i2c_algo_bit_data cx8800_i2c_algo_template = { | 152 | static struct i2c_algo_bit_data cx8800_i2c_algo_template = { |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 461019dca901..286c85b6bdf9 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (c) 2003 Pavel Machek | 6 | * Copyright (c) 2003 Pavel Machek |
7 | * Copyright (c) 2004 Gerd Knorr | 7 | * Copyright (c) 2004 Gerd Knorr |
8 | * Copyright (c) 2004 Chris Pascoe | 8 | * Copyright (c) 2004, 2005 Chris Pascoe |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -29,9 +29,8 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
31 | 31 | ||
32 | #include <media/ir-common.h> | ||
33 | |||
34 | #include "cx88.h" | 32 | #include "cx88.h" |
33 | #include <media/ir-common.h> | ||
35 | 34 | ||
36 | /* ---------------------------------------------------------------------- */ | 35 | /* ---------------------------------------------------------------------- */ |
37 | 36 | ||
@@ -258,6 +257,114 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { | |||
258 | 257 | ||
259 | /* ---------------------------------------------------------------------- */ | 258 | /* ---------------------------------------------------------------------- */ |
260 | 259 | ||
260 | /* AVERTV STUDIO 303 Remote */ | ||
261 | static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { | ||
262 | [ 0x2a ] = KEY_KP1, | ||
263 | [ 0x32 ] = KEY_KP2, | ||
264 | [ 0x3a ] = KEY_KP3, | ||
265 | [ 0x4a ] = KEY_KP4, | ||
266 | [ 0x52 ] = KEY_KP5, | ||
267 | [ 0x5a ] = KEY_KP6, | ||
268 | [ 0x6a ] = KEY_KP7, | ||
269 | [ 0x72 ] = KEY_KP8, | ||
270 | [ 0x7a ] = KEY_KP9, | ||
271 | [ 0x0e ] = KEY_KP0, | ||
272 | |||
273 | [ 0x02 ] = KEY_POWER, | ||
274 | [ 0x22 ] = KEY_VIDEO, | ||
275 | [ 0x42 ] = KEY_AUDIO, | ||
276 | [ 0x62 ] = KEY_ZOOM, | ||
277 | [ 0x0a ] = KEY_TV, | ||
278 | [ 0x12 ] = KEY_CD, | ||
279 | [ 0x1a ] = KEY_TEXT, | ||
280 | |||
281 | [ 0x16 ] = KEY_SUBTITLE, | ||
282 | [ 0x1e ] = KEY_REWIND, | ||
283 | [ 0x06 ] = KEY_PRINT, | ||
284 | |||
285 | [ 0x2e ] = KEY_SEARCH, | ||
286 | [ 0x36 ] = KEY_SLEEP, | ||
287 | [ 0x3e ] = KEY_SHUFFLE, | ||
288 | [ 0x26 ] = KEY_MUTE, | ||
289 | |||
290 | [ 0x4e ] = KEY_RECORD, | ||
291 | [ 0x56 ] = KEY_PAUSE, | ||
292 | [ 0x5e ] = KEY_STOP, | ||
293 | [ 0x46 ] = KEY_PLAY, | ||
294 | |||
295 | [ 0x6e ] = KEY_RED, | ||
296 | [ 0x0b ] = KEY_GREEN, | ||
297 | [ 0x66 ] = KEY_YELLOW, | ||
298 | [ 0x03 ] = KEY_BLUE, | ||
299 | |||
300 | [ 0x76 ] = KEY_LEFT, | ||
301 | [ 0x7e ] = KEY_RIGHT, | ||
302 | [ 0x13 ] = KEY_DOWN, | ||
303 | [ 0x1b ] = KEY_UP, | ||
304 | }; | ||
305 | |||
306 | /* ---------------------------------------------------------------------- */ | ||
307 | |||
308 | /* DigitalNow DNTV Live! DVB-T Pro Remote */ | ||
309 | static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { | ||
310 | [ 0x16 ] = KEY_POWER, | ||
311 | [ 0x5b ] = KEY_HOME, | ||
312 | |||
313 | [ 0x55 ] = KEY_TV, /* live tv */ | ||
314 | [ 0x58 ] = KEY_TUNER, /* digital Radio */ | ||
315 | [ 0x5a ] = KEY_RADIO, /* FM radio */ | ||
316 | [ 0x59 ] = KEY_DVD, /* dvd menu */ | ||
317 | [ 0x03 ] = KEY_1, | ||
318 | [ 0x01 ] = KEY_2, | ||
319 | [ 0x06 ] = KEY_3, | ||
320 | [ 0x09 ] = KEY_4, | ||
321 | [ 0x1d ] = KEY_5, | ||
322 | [ 0x1f ] = KEY_6, | ||
323 | [ 0x0d ] = KEY_7, | ||
324 | [ 0x19 ] = KEY_8, | ||
325 | [ 0x1b ] = KEY_9, | ||
326 | [ 0x0c ] = KEY_CANCEL, | ||
327 | [ 0x15 ] = KEY_0, | ||
328 | [ 0x4a ] = KEY_CLEAR, | ||
329 | [ 0x13 ] = KEY_BACK, | ||
330 | [ 0x00 ] = KEY_TAB, | ||
331 | [ 0x4b ] = KEY_UP, | ||
332 | [ 0x4e ] = KEY_LEFT, | ||
333 | [ 0x4f ] = KEY_OK, | ||
334 | [ 0x52 ] = KEY_RIGHT, | ||
335 | [ 0x51 ] = KEY_DOWN, | ||
336 | [ 0x1e ] = KEY_VOLUMEUP, | ||
337 | [ 0x0a ] = KEY_VOLUMEDOWN, | ||
338 | [ 0x02 ] = KEY_CHANNELDOWN, | ||
339 | [ 0x05 ] = KEY_CHANNELUP, | ||
340 | [ 0x11 ] = KEY_RECORD, | ||
341 | [ 0x14 ] = KEY_PLAY, | ||
342 | [ 0x4c ] = KEY_PAUSE, | ||
343 | [ 0x1a ] = KEY_STOP, | ||
344 | [ 0x40 ] = KEY_REWIND, | ||
345 | [ 0x12 ] = KEY_FASTFORWARD, | ||
346 | [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ | ||
347 | [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ | ||
348 | [ 0x54 ] = KEY_CAMERA, /* capture */ | ||
349 | [ 0x50 ] = KEY_LANGUAGE, /* sap */ | ||
350 | [ 0x47 ] = KEY_TV2, /* pip */ | ||
351 | [ 0x4d ] = KEY_SCREEN, | ||
352 | [ 0x43 ] = KEY_SUBTITLE, | ||
353 | [ 0x10 ] = KEY_MUTE, | ||
354 | [ 0x49 ] = KEY_AUDIO, /* l/r */ | ||
355 | [ 0x07 ] = KEY_SLEEP, | ||
356 | [ 0x08 ] = KEY_VIDEO, /* a/v */ | ||
357 | [ 0x0e ] = KEY_PREVIOUS, /* recall */ | ||
358 | [ 0x45 ] = KEY_ZOOM, /* zoom + */ | ||
359 | [ 0x46 ] = KEY_ANGLE, /* zoom - */ | ||
360 | [ 0x56 ] = KEY_RED, | ||
361 | [ 0x57 ] = KEY_GREEN, | ||
362 | [ 0x5c ] = KEY_YELLOW, | ||
363 | [ 0x5d ] = KEY_BLUE, | ||
364 | }; | ||
365 | |||
366 | /* ---------------------------------------------------------------------- */ | ||
367 | |||
261 | struct cx88_IR { | 368 | struct cx88_IR { |
262 | struct cx88_core *core; | 369 | struct cx88_core *core; |
263 | struct input_dev *input; | 370 | struct input_dev *input; |
@@ -266,7 +373,7 @@ struct cx88_IR { | |||
266 | char phys[32]; | 373 | char phys[32]; |
267 | 374 | ||
268 | /* sample from gpio pin 16 */ | 375 | /* sample from gpio pin 16 */ |
269 | int sampling; | 376 | u32 sampling; |
270 | u32 samples[16]; | 377 | u32 samples[16]; |
271 | int scount; | 378 | int scount; |
272 | unsigned long release; | 379 | unsigned long release; |
@@ -384,10 +491,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
384 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 491 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
385 | ir_codes = ir_codes_cinergy_1400; | 492 | ir_codes = ir_codes_cinergy_1400; |
386 | ir_type = IR_TYPE_PD; | 493 | ir_type = IR_TYPE_PD; |
387 | ir->sampling = 1; | 494 | ir->sampling = 0xeb04; /* address */ |
388 | break; | 495 | break; |
389 | case CX88_BOARD_HAUPPAUGE: | 496 | case CX88_BOARD_HAUPPAUGE: |
390 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 497 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
498 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
499 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
500 | case CX88_BOARD_HAUPPAUGE_HVR1100: | ||
391 | ir_codes = ir_codes_hauppauge_new; | 501 | ir_codes = ir_codes_hauppauge_new; |
392 | ir_type = IR_TYPE_RC5; | 502 | ir_type = IR_TYPE_RC5; |
393 | ir->sampling = 1; | 503 | ir->sampling = 1; |
@@ -427,6 +537,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
427 | ir->mask_keyup = 0x40; | 537 | ir->mask_keyup = 0x40; |
428 | ir->polling = 1; /* ms */ | 538 | ir->polling = 1; /* ms */ |
429 | break; | 539 | break; |
540 | case CX88_BOARD_AVERTV_303: | ||
541 | case CX88_BOARD_AVERTV_STUDIO_303: | ||
542 | ir_codes = ir_codes_avertv_303; | ||
543 | ir->gpio_addr = MO_GP2_IO; | ||
544 | ir->mask_keycode = 0xfb; | ||
545 | ir->mask_keydown = 0x02; | ||
546 | ir->polling = 50; /* ms */ | ||
547 | break; | ||
548 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | ||
549 | ir_codes = ir_codes_dntv_live_dvbt_pro; | ||
550 | ir_type = IR_TYPE_PD; | ||
551 | ir->sampling = 0xff00; /* address */ | ||
552 | break; | ||
430 | } | 553 | } |
431 | 554 | ||
432 | if (NULL == ir_codes) { | 555 | if (NULL == ir_codes) { |
@@ -484,6 +607,10 @@ int cx88_ir_fini(struct cx88_core *core) | |||
484 | if (NULL == ir) | 607 | if (NULL == ir) |
485 | return 0; | 608 | return 0; |
486 | 609 | ||
610 | if (ir->sampling) { | ||
611 | cx_write(MO_DDSCFG_IO, 0x0); | ||
612 | core->pci_irqmask &= ~(1 << 18); | ||
613 | } | ||
487 | if (ir->polling) { | 614 | if (ir->polling) { |
488 | del_timer(&ir->timer); | 615 | del_timer(&ir->timer); |
489 | flush_scheduled_work(); | 616 | flush_scheduled_work(); |
@@ -535,6 +662,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
535 | /* decode it */ | 662 | /* decode it */ |
536 | switch (core->board) { | 663 | switch (core->board) { |
537 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 664 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
665 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | ||
538 | ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); | 666 | ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); |
539 | 667 | ||
540 | if (ircode == 0xffffffff) { /* decoding error */ | 668 | if (ircode == 0xffffffff) { /* decoding error */ |
@@ -550,7 +678,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
550 | break; | 678 | break; |
551 | } | 679 | } |
552 | 680 | ||
553 | if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ | 681 | if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */ |
554 | ir_dprintk("pulse distance decoded wrong address\n"); | 682 | ir_dprintk("pulse distance decoded wrong address\n"); |
555 | break; | 683 | break; |
556 | } | 684 | } |
@@ -567,6 +695,8 @@ void cx88_ir_irq(struct cx88_core *core) | |||
567 | break; | 695 | break; |
568 | case CX88_BOARD_HAUPPAUGE: | 696 | case CX88_BOARD_HAUPPAUGE: |
569 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 697 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
698 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
699 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
570 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | 700 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); |
571 | ir_dprintk("biphase decoded: %x\n", ircode); | 701 | ir_dprintk("biphase decoded: %x\n", ircode); |
572 | if ((ircode & 0xfffff000) != 0x3000) | 702 | if ((ircode & 0xfffff000) != 0x3000) |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 35e6d0c2b872..c79cc1d2bf8b 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -78,6 +78,11 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
78 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: | 78 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
79 | cx_write(TS_SOP_STAT, 1<<13); | 79 | cx_write(TS_SOP_STAT, 1<<13); |
80 | break; | 80 | break; |
81 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
82 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
83 | cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ | ||
84 | udelay(100); | ||
85 | break; | ||
81 | default: | 86 | default: |
82 | cx_write(TS_SOP_STAT, 0x00); | 87 | cx_write(TS_SOP_STAT, 0x00); |
83 | break; | 88 | break; |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index a1b120c8a9b5..24118e43e73a 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -132,14 +132,22 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
132 | { | 132 | { |
133 | u32 volume; | 133 | u32 volume; |
134 | 134 | ||
135 | #ifndef USING_CX88_ALSA | ||
135 | /* restart dma; This avoids buzz in NICAM and is good in others */ | 136 | /* restart dma; This avoids buzz in NICAM and is good in others */ |
136 | cx88_stop_audio_dma(core); | 137 | cx88_stop_audio_dma(core); |
138 | #endif | ||
137 | cx_write(AUD_RATE_THRES_DMD, 0x000000C0); | 139 | cx_write(AUD_RATE_THRES_DMD, 0x000000C0); |
140 | #ifndef USING_CX88_ALSA | ||
138 | cx88_start_audio_dma(core); | 141 | cx88_start_audio_dma(core); |
142 | #endif | ||
139 | 143 | ||
140 | if (cx88_boards[core->board].blackbird) { | 144 | if (cx88_boards[core->board].blackbird) { |
141 | /* sets sound input from external adc */ | 145 | /* sets sound input from external adc */ |
142 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); | 146 | if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) |
147 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); | ||
148 | else | ||
149 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); | ||
150 | |||
143 | cx_write(AUD_I2SINPUTCNTL, 4); | 151 | cx_write(AUD_I2SINPUTCNTL, 4); |
144 | cx_write(AUD_BAUDRATE, 1); | 152 | cx_write(AUD_BAUDRATE, 1); |
145 | /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ | 153 | /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 24a48f8a48c1..9a02515fe18b 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/div64.h> | 33 | #include <asm/div64.h> |
34 | 34 | ||
35 | #include "cx88.h" | 35 | #include "cx88.h" |
36 | #include <media/v4l2-common.h> | ||
36 | 37 | ||
37 | /* Include V4L1 specific functions. Should be removed soon */ | 38 | /* Include V4L1 specific functions. Should be removed soon */ |
38 | #include <linux/videodev.h> | 39 | #include <linux/videodev.h> |
@@ -240,7 +241,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
240 | .minimum = 0, | 241 | .minimum = 0, |
241 | .maximum = 0xff, | 242 | .maximum = 0xff, |
242 | .step = 1, | 243 | .step = 1, |
243 | .default_value = 0, | 244 | .default_value = 0x3f, |
244 | .type = V4L2_CTRL_TYPE_INTEGER, | 245 | .type = V4L2_CTRL_TYPE_INTEGER, |
245 | }, | 246 | }, |
246 | .off = 0, | 247 | .off = 0, |
@@ -271,7 +272,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
271 | .minimum = 0, | 272 | .minimum = 0, |
272 | .maximum = 0xff, | 273 | .maximum = 0xff, |
273 | .step = 1, | 274 | .step = 1, |
274 | .default_value = 0, | 275 | .default_value = 0x7f, |
275 | .type = V4L2_CTRL_TYPE_INTEGER, | 276 | .type = V4L2_CTRL_TYPE_INTEGER, |
276 | }, | 277 | }, |
277 | .off = 0, | 278 | .off = 0, |
@@ -285,6 +286,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
285 | .name = "Mute", | 286 | .name = "Mute", |
286 | .minimum = 0, | 287 | .minimum = 0, |
287 | .maximum = 1, | 288 | .maximum = 1, |
289 | .default_value = 1, | ||
288 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 290 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
289 | }, | 291 | }, |
290 | .reg = AUD_VOL_CTL, | 292 | .reg = AUD_VOL_CTL, |
@@ -298,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
298 | .minimum = 0, | 300 | .minimum = 0, |
299 | .maximum = 0x3f, | 301 | .maximum = 0x3f, |
300 | .step = 1, | 302 | .step = 1, |
301 | .default_value = 0, | 303 | .default_value = 0x1f, |
302 | .type = V4L2_CTRL_TYPE_INTEGER, | 304 | .type = V4L2_CTRL_TYPE_INTEGER, |
303 | }, | 305 | }, |
304 | .reg = AUD_VOL_CTL, | 306 | .reg = AUD_VOL_CTL, |
@@ -917,6 +919,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
917 | ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; | 919 | ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; |
918 | break; | 920 | break; |
919 | } | 921 | } |
922 | printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", | ||
923 | ctl->id, c->reg, ctl->value, | ||
924 | c->mask, c->sreg ? " [shadowed]" : ""); | ||
920 | return 0; | 925 | return 0; |
921 | } | 926 | } |
922 | 927 | ||
@@ -925,13 +930,13 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
925 | { | 930 | { |
926 | /* struct cx88_core *core = dev->core; */ | 931 | /* struct cx88_core *core = dev->core; */ |
927 | struct cx88_ctrl *c = NULL; | 932 | struct cx88_ctrl *c = NULL; |
928 | u32 v_sat_value; | 933 | u32 value,mask; |
929 | u32 value; | ||
930 | int i; | 934 | int i; |
931 | 935 | for (i = 0; i < CX8800_CTLS; i++) { | |
932 | for (i = 0; i < CX8800_CTLS; i++) | 936 | if (cx8800_ctls[i].v.id == ctl->id) { |
933 | if (cx8800_ctls[i].v.id == ctl->id) | ||
934 | c = &cx8800_ctls[i]; | 937 | c = &cx8800_ctls[i]; |
938 | } | ||
939 | } | ||
935 | if (NULL == c) | 940 | if (NULL == c) |
936 | return -EINVAL; | 941 | return -EINVAL; |
937 | 942 | ||
@@ -939,6 +944,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
939 | ctl->value = c->v.minimum; | 944 | ctl->value = c->v.minimum; |
940 | if (ctl->value > c->v.maximum) | 945 | if (ctl->value > c->v.maximum) |
941 | ctl->value = c->v.maximum; | 946 | ctl->value = c->v.maximum; |
947 | mask=c->mask; | ||
942 | switch (ctl->id) { | 948 | switch (ctl->id) { |
943 | case V4L2_CID_AUDIO_BALANCE: | 949 | case V4L2_CID_AUDIO_BALANCE: |
944 | value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; | 950 | value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; |
@@ -948,56 +954,44 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
948 | break; | 954 | break; |
949 | case V4L2_CID_SATURATION: | 955 | case V4L2_CID_SATURATION: |
950 | /* special v_sat handling */ | 956 | /* special v_sat handling */ |
951 | v_sat_value = ctl->value - (0x7f - 0x5a); | 957 | |
952 | if (v_sat_value > 0xff) | 958 | value = ((ctl->value - c->off) << c->shift) & c->mask; |
953 | v_sat_value = 0xff; | 959 | |
954 | if (v_sat_value < 0x00) | 960 | if (core->tvnorm->id & V4L2_STD_SECAM) { |
955 | v_sat_value = 0x00; | 961 | /* For SECAM, both U and V sat should be equal */ |
956 | cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8); | 962 | value=value<<8|value; |
957 | /* fall through to default route for u_sat */ | 963 | } else { |
964 | /* Keeps U Saturation proportional to V Sat */ | ||
965 | value=(value*0x5a)/0x7f<<8|value; | ||
966 | } | ||
967 | mask=0xffff; | ||
968 | break; | ||
958 | default: | 969 | default: |
959 | value = ((ctl->value - c->off) << c->shift) & c->mask; | 970 | value = ((ctl->value - c->off) << c->shift) & c->mask; |
960 | break; | 971 | break; |
961 | } | 972 | } |
962 | dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n", | 973 | printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", |
963 | ctl->id, c->reg, value, c->sreg ? " [shadowed]" : ""); | 974 | ctl->id, c->reg, value, |
975 | mask, c->sreg ? " [shadowed]" : ""); | ||
964 | if (c->sreg) { | 976 | if (c->sreg) { |
965 | cx_sandor(c->sreg, c->reg, c->mask, value); | 977 | cx_sandor(c->sreg, c->reg, mask, value); |
966 | } else { | 978 | } else { |
967 | cx_andor(c->reg, c->mask, value); | 979 | cx_andor(c->reg, mask, value); |
968 | } | 980 | } |
969 | return 0; | 981 | return 0; |
970 | } | 982 | } |
971 | 983 | ||
972 | /* static void init_controls(struct cx8800_dev *dev) */ | ||
973 | static void init_controls(struct cx88_core *core) | 984 | static void init_controls(struct cx88_core *core) |
974 | { | 985 | { |
975 | static struct v4l2_control mute = { | 986 | struct v4l2_control ctrl; |
976 | .id = V4L2_CID_AUDIO_MUTE, | 987 | int i; |
977 | .value = 1, | ||
978 | }; | ||
979 | static struct v4l2_control volume = { | ||
980 | .id = V4L2_CID_AUDIO_VOLUME, | ||
981 | .value = 0x3f, | ||
982 | }; | ||
983 | static struct v4l2_control hue = { | ||
984 | .id = V4L2_CID_HUE, | ||
985 | .value = 0x80, | ||
986 | }; | ||
987 | static struct v4l2_control contrast = { | ||
988 | .id = V4L2_CID_CONTRAST, | ||
989 | .value = 0x80, | ||
990 | }; | ||
991 | static struct v4l2_control brightness = { | ||
992 | .id = V4L2_CID_BRIGHTNESS, | ||
993 | .value = 0x80, | ||
994 | }; | ||
995 | 988 | ||
996 | set_control(core,&mute); | 989 | for (i = 0; i < CX8800_CTLS; i++) { |
997 | set_control(core,&volume); | 990 | ctrl.id=cx8800_ctls[i].v.id; |
998 | set_control(core,&hue); | 991 | ctrl.value=cx8800_ctls[i].v.default_value |
999 | set_control(core,&contrast); | 992 | +cx8800_ctls[i].off; |
1000 | set_control(core,&brightness); | 993 | set_control(core, &ctrl); |
994 | } | ||
1001 | } | 995 | } |
1002 | 996 | ||
1003 | /* ------------------------------------------------------------------ */ | 997 | /* ------------------------------------------------------------------ */ |
@@ -1125,7 +1119,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1125 | int err; | 1119 | int err; |
1126 | 1120 | ||
1127 | if (video_debug > 1) | 1121 | if (video_debug > 1) |
1128 | cx88_print_ioctl(core->name,cmd); | 1122 | v4l_print_ioctl(core->name,cmd); |
1129 | switch (cmd) { | 1123 | switch (cmd) { |
1130 | 1124 | ||
1131 | /* --- capabilities ------------------------------------------ */ | 1125 | /* --- capabilities ------------------------------------------ */ |
@@ -1261,7 +1255,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
1261 | 1255 | ||
1262 | dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); | 1256 | dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); |
1263 | if (video_debug > 1) | 1257 | if (video_debug > 1) |
1264 | cx88_print_ioctl(core->name,cmd); | 1258 | v4l_print_ioctl(core->name,cmd); |
1265 | 1259 | ||
1266 | switch (cmd) { | 1260 | switch (cmd) { |
1267 | /* ---------- tv norms ---------- */ | 1261 | /* ---------- tv norms ---------- */ |
@@ -1481,7 +1475,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1481 | struct cx88_core *core = dev->core; | 1475 | struct cx88_core *core = dev->core; |
1482 | 1476 | ||
1483 | if (video_debug > 1) | 1477 | if (video_debug > 1) |
1484 | cx88_print_ioctl(core->name,cmd); | 1478 | v4l_print_ioctl(core->name,cmd); |
1485 | 1479 | ||
1486 | switch (cmd) { | 1480 | switch (cmd) { |
1487 | case VIDIOC_QUERYCAP: | 1481 | case VIDIOC_QUERYCAP: |
@@ -1740,6 +1734,7 @@ static struct file_operations video_fops = | |||
1740 | .poll = video_poll, | 1734 | .poll = video_poll, |
1741 | .mmap = video_mmap, | 1735 | .mmap = video_mmap, |
1742 | .ioctl = video_ioctl, | 1736 | .ioctl = video_ioctl, |
1737 | .compat_ioctl = v4l_compat_ioctl32, | ||
1743 | .llseek = no_llseek, | 1738 | .llseek = no_llseek, |
1744 | }; | 1739 | }; |
1745 | 1740 | ||
@@ -1767,6 +1762,7 @@ static struct file_operations radio_fops = | |||
1767 | .open = video_open, | 1762 | .open = video_open, |
1768 | .release = video_release, | 1763 | .release = video_release, |
1769 | .ioctl = radio_ioctl, | 1764 | .ioctl = radio_ioctl, |
1765 | .compat_ioctl = v4l_compat_ioctl32, | ||
1770 | .llseek = no_llseek, | 1766 | .llseek = no_llseek, |
1771 | }; | 1767 | }; |
1772 | 1768 | ||
@@ -1928,8 +1924,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1928 | 1924 | ||
1929 | /* initial device configuration */ | 1925 | /* initial device configuration */ |
1930 | down(&core->lock); | 1926 | down(&core->lock); |
1931 | init_controls(core); | ||
1932 | cx88_set_tvnorm(core,tvnorms); | 1927 | cx88_set_tvnorm(core,tvnorms); |
1928 | init_controls(core); | ||
1933 | video_mux(core,0); | 1929 | video_mux(core,0); |
1934 | up(&core->lock); | 1930 | up(&core->lock); |
1935 | 1931 | ||
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c new file mode 100644 index 000000000000..372cd29cedbd --- /dev/null +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | |||
3 | cx88-vp3054-i2c.c -- support for the secondary I2C bus of the | ||
4 | DNTV Live! DVB-T Pro (VP-3054), wired as: | ||
5 | GPIO[0] -> SCL, GPIO[1] -> SDA | ||
6 | |||
7 | (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #include <asm/io.h> | ||
30 | |||
31 | #include "cx88.h" | ||
32 | #include "cx88-vp3054-i2c.h" | ||
33 | |||
34 | |||
35 | /* ----------------------------------------------------------------------- */ | ||
36 | |||
37 | static void vp3054_bit_setscl(void *data, int state) | ||
38 | { | ||
39 | struct cx8802_dev *dev = data; | ||
40 | struct cx88_core *core = dev->core; | ||
41 | struct vp3054_i2c_state *vp3054_i2c = dev->card_priv; | ||
42 | |||
43 | if (state) { | ||
44 | vp3054_i2c->state |= 0x0001; /* SCL high */ | ||
45 | vp3054_i2c->state &= ~0x0100; /* external pullup */ | ||
46 | } else { | ||
47 | vp3054_i2c->state &= ~0x0001; /* SCL low */ | ||
48 | vp3054_i2c->state |= 0x0100; /* drive pin */ | ||
49 | } | ||
50 | cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state); | ||
51 | cx_read(MO_GP0_IO); | ||
52 | } | ||
53 | |||
54 | static void vp3054_bit_setsda(void *data, int state) | ||
55 | { | ||
56 | struct cx8802_dev *dev = data; | ||
57 | struct cx88_core *core = dev->core; | ||
58 | struct vp3054_i2c_state *vp3054_i2c = dev->card_priv; | ||
59 | |||
60 | if (state) { | ||
61 | vp3054_i2c->state |= 0x0002; /* SDA high */ | ||
62 | vp3054_i2c->state &= ~0x0200; /* tristate pin */ | ||
63 | } else { | ||
64 | vp3054_i2c->state &= ~0x0002; /* SDA low */ | ||
65 | vp3054_i2c->state |= 0x0200; /* drive pin */ | ||
66 | } | ||
67 | cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state); | ||
68 | cx_read(MO_GP0_IO); | ||
69 | } | ||
70 | |||
71 | static int vp3054_bit_getscl(void *data) | ||
72 | { | ||
73 | struct cx8802_dev *dev = data; | ||
74 | struct cx88_core *core = dev->core; | ||
75 | u32 state; | ||
76 | |||
77 | state = cx_read(MO_GP0_IO); | ||
78 | return (state & 0x01) ? 1 : 0; | ||
79 | } | ||
80 | |||
81 | static int vp3054_bit_getsda(void *data) | ||
82 | { | ||
83 | struct cx8802_dev *dev = data; | ||
84 | struct cx88_core *core = dev->core; | ||
85 | u32 state; | ||
86 | |||
87 | state = cx_read(MO_GP0_IO); | ||
88 | return (state & 0x02) ? 1 : 0; | ||
89 | } | ||
90 | |||
91 | /* ----------------------------------------------------------------------- */ | ||
92 | |||
93 | static struct i2c_algo_bit_data vp3054_i2c_algo_template = { | ||
94 | .setsda = vp3054_bit_setsda, | ||
95 | .setscl = vp3054_bit_setscl, | ||
96 | .getsda = vp3054_bit_getsda, | ||
97 | .getscl = vp3054_bit_getscl, | ||
98 | .udelay = 16, | ||
99 | .mdelay = 10, | ||
100 | .timeout = 200, | ||
101 | }; | ||
102 | |||
103 | /* ----------------------------------------------------------------------- */ | ||
104 | |||
105 | static struct i2c_adapter vp3054_i2c_adap_template = { | ||
106 | .name = "cx2388x", | ||
107 | .owner = THIS_MODULE, | ||
108 | .id = I2C_HW_B_CX2388x, | ||
109 | }; | ||
110 | |||
111 | static struct i2c_client vp3054_i2c_client_template = { | ||
112 | .name = "VP-3054", | ||
113 | }; | ||
114 | |||
115 | int vp3054_i2c_probe(struct cx8802_dev *dev) | ||
116 | { | ||
117 | struct cx88_core *core = dev->core; | ||
118 | struct vp3054_i2c_state *vp3054_i2c; | ||
119 | int rc; | ||
120 | |||
121 | if (core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO) | ||
122 | return 0; | ||
123 | |||
124 | dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL); | ||
125 | if (dev->card_priv == NULL) | ||
126 | return -ENOMEM; | ||
127 | vp3054_i2c = dev->card_priv; | ||
128 | |||
129 | memcpy(&vp3054_i2c->adap, &vp3054_i2c_adap_template, | ||
130 | sizeof(vp3054_i2c->adap)); | ||
131 | memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, | ||
132 | sizeof(vp3054_i2c->algo)); | ||
133 | memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template, | ||
134 | sizeof(vp3054_i2c->client)); | ||
135 | |||
136 | vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL; | ||
137 | |||
138 | vp3054_i2c->adap.dev.parent = &dev->pci->dev; | ||
139 | strlcpy(vp3054_i2c->adap.name, core->name, | ||
140 | sizeof(vp3054_i2c->adap.name)); | ||
141 | vp3054_i2c->algo.data = dev; | ||
142 | i2c_set_adapdata(&vp3054_i2c->adap, dev); | ||
143 | vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; | ||
144 | vp3054_i2c->client.adapter = &vp3054_i2c->adap; | ||
145 | |||
146 | vp3054_bit_setscl(dev,1); | ||
147 | vp3054_bit_setsda(dev,1); | ||
148 | |||
149 | rc = i2c_bit_add_bus(&vp3054_i2c->adap); | ||
150 | if (0 != rc) { | ||
151 | printk("%s: vp3054_i2c register FAILED\n", core->name); | ||
152 | |||
153 | kfree(dev->card_priv); | ||
154 | dev->card_priv = NULL; | ||
155 | } | ||
156 | |||
157 | return rc; | ||
158 | } | ||
159 | |||
160 | void vp3054_i2c_remove(struct cx8802_dev *dev) | ||
161 | { | ||
162 | struct vp3054_i2c_state *vp3054_i2c = dev->card_priv; | ||
163 | |||
164 | if (vp3054_i2c == NULL || | ||
165 | dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO) | ||
166 | return; | ||
167 | |||
168 | i2c_bit_del_bus(&vp3054_i2c->adap); | ||
169 | kfree(vp3054_i2c); | ||
170 | } | ||
171 | |||
172 | EXPORT_SYMBOL(vp3054_i2c_probe); | ||
173 | EXPORT_SYMBOL(vp3054_i2c_remove); | ||
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h new file mode 100644 index 000000000000..b7a0a04d2423 --- /dev/null +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | |||
3 | cx88-vp3054-i2c.h -- support for the secondary I2C bus of the | ||
4 | DNTV Live! DVB-T Pro (VP-3054), wired as: | ||
5 | GPIO[0] -> SCL, GPIO[1] -> SDA | ||
6 | |||
7 | (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | /* ----------------------------------------------------------------------- */ | ||
26 | struct vp3054_i2c_state { | ||
27 | struct i2c_adapter adap; | ||
28 | struct i2c_algo_bit_data algo; | ||
29 | struct i2c_client client; | ||
30 | u32 state; | ||
31 | }; | ||
32 | |||
33 | /* ----------------------------------------------------------------------- */ | ||
34 | int vp3054_i2c_probe(struct cx8802_dev *dev); | ||
35 | void vp3054_i2c_remove(struct cx8802_dev *dev); | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 77beafc5c327..e9fd55b57fa6 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -179,6 +179,14 @@ extern struct sram_channel cx88_sram_channels[]; | |||
179 | #define CX88_BOARD_ATI_HDTVWONDER 34 | 179 | #define CX88_BOARD_ATI_HDTVWONDER 34 |
180 | #define CX88_BOARD_WINFAST_DTV1000 35 | 180 | #define CX88_BOARD_WINFAST_DTV1000 35 |
181 | #define CX88_BOARD_AVERTV_303 36 | 181 | #define CX88_BOARD_AVERTV_303 36 |
182 | #define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37 | ||
183 | #define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38 | ||
184 | #define CX88_BOARD_KWORLD_DVBS_100 39 | ||
185 | #define CX88_BOARD_HAUPPAUGE_HVR1100 40 | ||
186 | #define CX88_BOARD_HAUPPAUGE_HVR1100LP 41 | ||
187 | #define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 | ||
188 | #define CX88_BOARD_KWORLD_DVB_T_CX22702 43 | ||
189 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 | ||
182 | 190 | ||
183 | enum cx88_itype { | 191 | enum cx88_itype { |
184 | CX88_VMUX_COMPOSITE1 = 1, | 192 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -280,6 +288,9 @@ struct cx88_core { | |||
280 | unsigned int tda9887_conf; | 288 | unsigned int tda9887_conf; |
281 | unsigned int has_radio; | 289 | unsigned int has_radio; |
282 | 290 | ||
291 | /* Supported V4L _STD_ tuner formats */ | ||
292 | unsigned int tuner_formats; | ||
293 | |||
283 | /* config info -- dvb */ | 294 | /* config info -- dvb */ |
284 | struct dvb_pll_desc *pll_desc; | 295 | struct dvb_pll_desc *pll_desc; |
285 | unsigned int pll_addr; | 296 | unsigned int pll_addr; |
@@ -301,6 +312,9 @@ struct cx88_core { | |||
301 | 312 | ||
302 | /* various v4l controls */ | 313 | /* various v4l controls */ |
303 | u32 freq; | 314 | u32 freq; |
315 | |||
316 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ | ||
317 | struct cx8802_dev *dvbdev; | ||
304 | }; | 318 | }; |
305 | 319 | ||
306 | struct cx8800_dev; | 320 | struct cx8800_dev; |
@@ -411,6 +425,8 @@ struct cx8802_dev { | |||
411 | struct videobuf_dvb dvb; | 425 | struct videobuf_dvb dvb; |
412 | void* fe_handle; | 426 | void* fe_handle; |
413 | int (*fe_release)(void *handle); | 427 | int (*fe_release)(void *handle); |
428 | |||
429 | void *card_priv; | ||
414 | /* for switching modulation types */ | 430 | /* for switching modulation types */ |
415 | unsigned char ts_gen_cntrl; | 431 | unsigned char ts_gen_cntrl; |
416 | 432 | ||
@@ -447,7 +463,6 @@ struct cx8802_dev { | |||
447 | 463 | ||
448 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, | 464 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, |
449 | u32 bits, u32 mask); | 465 | u32 bits, u32 mask); |
450 | extern void cx88_print_ioctl(char *name, unsigned int cmd); | ||
451 | 466 | ||
452 | extern int cx88_core_irq(struct cx88_core *core, u32 status); | 467 | extern int cx88_core_irq(struct cx88_core *core, u32 status); |
453 | extern void cx88_wakeup(struct cx88_core *core, | 468 | extern void cx88_wakeup(struct cx88_core *core, |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 57779e63f35d..58f7b4194a0d 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <media/tuner.h> | 30 | #include <media/tuner.h> |
31 | #include <media/audiochip.h> | 31 | #include <media/audiochip.h> |
32 | #include <media/tveeprom.h> | 32 | #include <media/tveeprom.h> |
33 | #include <media/v4l2-common.h> | ||
33 | #include "msp3400.h" | 34 | #include "msp3400.h" |
34 | 35 | ||
35 | #include "em28xx.h" | 36 | #include "em28xx.h" |
@@ -261,7 +262,6 @@ void em28xx_card_setup(struct em28xx *dev) | |||
261 | /* request some modules */ | 262 | /* request some modules */ |
262 | if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { | 263 | if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { |
263 | struct tveeprom tv; | 264 | struct tveeprom tv; |
264 | struct v4l2_audioout ao; | ||
265 | #ifdef CONFIG_MODULES | 265 | #ifdef CONFIG_MODULES |
266 | request_module("tveeprom"); | 266 | request_module("tveeprom"); |
267 | request_module("ir-kbd-i2c"); | 267 | request_module("ir-kbd-i2c"); |
@@ -274,12 +274,8 @@ void em28xx_card_setup(struct em28xx *dev) | |||
274 | 274 | ||
275 | dev->tuner_type= tv.tuner_type; | 275 | dev->tuner_type= tv.tuner_type; |
276 | if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { | 276 | if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { |
277 | dev->i2s_speed=2048000; | ||
277 | dev->has_msp34xx=1; | 278 | dev->has_msp34xx=1; |
278 | memset (&ao,0,sizeof(ao)); | ||
279 | |||
280 | ao.index=2; | ||
281 | ao.mode=V4L2_AUDMODE_32BITS; | ||
282 | em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao); | ||
283 | } else | 279 | } else |
284 | dev->has_msp34xx=0; | 280 | dev->has_msp34xx=0; |
285 | } | 281 | } |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 0cfe75416ec6..dff3893f32fd 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ | 33 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ |
34 | 34 | ||
35 | static unsigned int core_debug; | 35 | static unsigned int core_debug = 0; |
36 | module_param(core_debug,int,0644); | 36 | module_param(core_debug,int,0644); |
37 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | 37 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); |
38 | 38 | ||
@@ -41,7 +41,7 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | |||
41 | printk(KERN_INFO "%s %s :"fmt, \ | 41 | printk(KERN_INFO "%s %s :"fmt, \ |
42 | dev->name, __FUNCTION__ , ##arg); } while (0) | 42 | dev->name, __FUNCTION__ , ##arg); } while (0) |
43 | 43 | ||
44 | static unsigned int reg_debug; | 44 | static unsigned int reg_debug = 0; |
45 | module_param(reg_debug,int,0644); | 45 | module_param(reg_debug,int,0644); |
46 | MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); | 46 | MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); |
47 | 47 | ||
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); | |||
50 | printk(KERN_INFO "%s %s :"fmt, \ | 50 | printk(KERN_INFO "%s %s :"fmt, \ |
51 | dev->name, __FUNCTION__ , ##arg); } while (0) | 51 | dev->name, __FUNCTION__ , ##arg); } while (0) |
52 | 52 | ||
53 | static unsigned int isoc_debug; | 53 | static unsigned int isoc_debug = 0; |
54 | module_param(isoc_debug,int,0644); | 54 | module_param(isoc_debug,int,0644); |
55 | MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); | 55 | MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); |
56 | 56 | ||
@@ -63,59 +63,6 @@ static int alt = EM28XX_PINOUT; | |||
63 | module_param(alt, int, 0644); | 63 | module_param(alt, int, 0644); |
64 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | 64 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); |
65 | 65 | ||
66 | /* ------------------------------------------------------------------ */ | ||
67 | /* debug help functions */ | ||
68 | |||
69 | static const char *v4l1_ioctls[] = { | ||
70 | "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", | ||
71 | "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", | ||
72 | "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", | ||
73 | "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", | ||
74 | "SMICROCODE", "GVBIFMT", "SVBIFMT" }; | ||
75 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
76 | |||
77 | static const char *v4l2_ioctls[] = { | ||
78 | "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", | ||
79 | "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", | ||
80 | "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", | ||
81 | "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", | ||
82 | "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", | ||
83 | "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", | ||
84 | "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", | ||
85 | "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", | ||
86 | "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", | ||
87 | "S_MODULATOR" | ||
88 | }; | ||
89 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | ||
90 | |||
91 | void em28xx_print_ioctl(char *name, unsigned int cmd) | ||
92 | { | ||
93 | char *dir; | ||
94 | |||
95 | switch (_IOC_DIR(cmd)) { | ||
96 | case _IOC_NONE: dir = "--"; break; | ||
97 | case _IOC_READ: dir = "r-"; break; | ||
98 | case _IOC_WRITE: dir = "-w"; break; | ||
99 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
100 | default: dir = "??"; break; | ||
101 | } | ||
102 | switch (_IOC_TYPE(cmd)) { | ||
103 | case 'v': | ||
104 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", | ||
105 | name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? | ||
106 | v4l1_ioctls[_IOC_NR(cmd)] : "???"); | ||
107 | break; | ||
108 | case 'V': | ||
109 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", | ||
110 | name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? | ||
111 | v4l2_ioctls[_IOC_NR(cmd)] : "???"); | ||
112 | break; | ||
113 | default: | ||
114 | printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", | ||
115 | name, cmd, dir, _IOC_NR(cmd)); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | 66 | ||
120 | /* | 67 | /* |
121 | * em28xx_request_buffers() | 68 | * em28xx_request_buffers() |
@@ -126,7 +73,7 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count) | |||
126 | const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ | 73 | const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ |
127 | void *buff = NULL; | 74 | void *buff = NULL; |
128 | u32 i; | 75 | u32 i; |
129 | em28xx_coredbg("requested %i buffers with size %zd", count, imagesize); | 76 | em28xx_coredbg("requested %i buffers with size %zi", count, imagesize); |
130 | if (count > EM28XX_NUM_FRAMES) | 77 | if (count > EM28XX_NUM_FRAMES) |
131 | count = EM28XX_NUM_FRAMES; | 78 | count = EM28XX_NUM_FRAMES; |
132 | 79 | ||
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index d14bcf4ceaea..0591a705b7a1 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/video_decoder.h> | 28 | #include <linux/video_decoder.h> |
29 | 29 | ||
30 | #include "em28xx.h" | 30 | #include "em28xx.h" |
31 | #include <media/v4l2-common.h> | ||
31 | #include <media/tuner.h> | 32 | #include <media/tuner.h> |
32 | 33 | ||
33 | /* ----------------------------------------------------------- */ | 34 | /* ----------------------------------------------------------- */ |
@@ -486,9 +487,7 @@ static struct i2c_adapter em28xx_adap_template = { | |||
486 | .inc_use = inc_use, | 487 | .inc_use = inc_use, |
487 | .dec_use = dec_use, | 488 | .dec_use = dec_use, |
488 | #endif | 489 | #endif |
489 | #ifdef I2C_CLASS_TV_ANALOG | ||
490 | .class = I2C_CLASS_TV_ANALOG, | 490 | .class = I2C_CLASS_TV_ANALOG, |
491 | #endif | ||
492 | .name = "em28xx", | 491 | .name = "em28xx", |
493 | .id = I2C_HW_B_EM28XX, | 492 | .id = I2C_HW_B_EM28XX, |
494 | .algo = &em28xx_algo, | 493 | .algo = &em28xx_algo, |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 3a56120397ae..fdc255918dde 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include "em28xx.h" | 33 | #include "em28xx.h" |
34 | #include <media/tuner.h> | 34 | #include <media/tuner.h> |
35 | #include <media/v4l2-common.h> | ||
35 | 36 | ||
36 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | 37 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
37 | "Markus Rechberger <mrechberger@gmail.com>, " \ | 38 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
@@ -106,8 +107,32 @@ static const unsigned char saa7114_i2c_init[] = { | |||
106 | #define TVNORMS ARRAY_SIZE(tvnorms) | 107 | #define TVNORMS ARRAY_SIZE(tvnorms) |
107 | 108 | ||
108 | /* supported controls */ | 109 | /* supported controls */ |
110 | /* Common to all boards */ | ||
109 | static struct v4l2_queryctrl em28xx_qctrl[] = { | 111 | static struct v4l2_queryctrl em28xx_qctrl[] = { |
110 | { | 112 | { |
113 | .id = V4L2_CID_AUDIO_VOLUME, | ||
114 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
115 | .name = "Volume", | ||
116 | .minimum = 0x0, | ||
117 | .maximum = 0x1f, | ||
118 | .step = 0x1, | ||
119 | .default_value = 0x1f, | ||
120 | .flags = 0, | ||
121 | },{ | ||
122 | .id = V4L2_CID_AUDIO_MUTE, | ||
123 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
124 | .name = "Mute", | ||
125 | .minimum = 0, | ||
126 | .maximum = 1, | ||
127 | .step = 1, | ||
128 | .default_value = 1, | ||
129 | .flags = 0, | ||
130 | } | ||
131 | }; | ||
132 | |||
133 | /* FIXME: These are specific to saa711x - should be moved to its code */ | ||
134 | static struct v4l2_queryctrl saa711x_qctrl[] = { | ||
135 | { | ||
111 | .id = V4L2_CID_BRIGHTNESS, | 136 | .id = V4L2_CID_BRIGHTNESS, |
112 | .type = V4L2_CTRL_TYPE_INTEGER, | 137 | .type = V4L2_CTRL_TYPE_INTEGER, |
113 | .name = "Brightness", | 138 | .name = "Brightness", |
@@ -135,24 +160,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
135 | .default_value = 0x10, | 160 | .default_value = 0x10, |
136 | .flags = 0, | 161 | .flags = 0, |
137 | },{ | 162 | },{ |
138 | .id = V4L2_CID_AUDIO_VOLUME, | ||
139 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
140 | .name = "Volume", | ||
141 | .minimum = 0x0, | ||
142 | .maximum = 0x1f, | ||
143 | .step = 0x1, | ||
144 | .default_value = 0x1f, | ||
145 | .flags = 0, | ||
146 | },{ | ||
147 | .id = V4L2_CID_AUDIO_MUTE, | ||
148 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
149 | .name = "Mute", | ||
150 | .minimum = 0, | ||
151 | .maximum = 1, | ||
152 | .step = 1, | ||
153 | .default_value = 1, | ||
154 | .flags = 0, | ||
155 | },{ | ||
156 | .id = V4L2_CID_RED_BALANCE, | 163 | .id = V4L2_CID_RED_BALANCE, |
157 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
158 | .name = "Red chroma balance", | 165 | .name = "Red chroma balance", |
@@ -179,7 +186,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
179 | .step = 0x1, | 186 | .step = 0x1, |
180 | .default_value = 0x20, | 187 | .default_value = 0x20, |
181 | .flags = 0, | 188 | .flags = 0, |
182 | } | 189 | } |
183 | }; | 190 | }; |
184 | 191 | ||
185 | static struct usb_driver em28xx_usb_driver; | 192 | static struct usb_driver em28xx_usb_driver; |
@@ -280,6 +287,8 @@ static void video_mux(struct em28xx *dev, int index) | |||
280 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); | 287 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); |
281 | 288 | ||
282 | if (dev->has_msp34xx) { | 289 | if (dev->has_msp34xx) { |
290 | if (dev->i2s_speed) | ||
291 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); | ||
283 | em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); | 292 | em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); |
284 | ainput = EM28XX_AUDIO_SRC_TUNER; | 293 | ainput = EM28XX_AUDIO_SRC_TUNER; |
285 | em28xx_audio_source(dev, ainput); | 294 | em28xx_audio_source(dev, ainput); |
@@ -674,7 +683,6 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
674 | */ | 683 | */ |
675 | static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | 684 | static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) |
676 | { | 685 | { |
677 | s32 tmp; | ||
678 | switch (ctrl->id) { | 686 | switch (ctrl->id) { |
679 | case V4L2_CID_AUDIO_MUTE: | 687 | case V4L2_CID_AUDIO_MUTE: |
680 | ctrl->value = dev->mute; | 688 | ctrl->value = dev->mute; |
@@ -682,6 +690,16 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | |||
682 | case V4L2_CID_AUDIO_VOLUME: | 690 | case V4L2_CID_AUDIO_VOLUME: |
683 | ctrl->value = dev->volume; | 691 | ctrl->value = dev->volume; |
684 | return 0; | 692 | return 0; |
693 | default: | ||
694 | return -EINVAL; | ||
695 | } | ||
696 | } | ||
697 | |||
698 | /*FIXME: should be moved to saa711x */ | ||
699 | static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | ||
700 | { | ||
701 | s32 tmp; | ||
702 | switch (ctrl->id) { | ||
685 | case V4L2_CID_BRIGHTNESS: | 703 | case V4L2_CID_BRIGHTNESS: |
686 | if ((tmp = em28xx_brightness_get(dev)) < 0) | 704 | if ((tmp = em28xx_brightness_get(dev)) < 0) |
687 | return -EIO; | 705 | return -EIO; |
@@ -731,6 +749,15 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | |||
731 | case V4L2_CID_AUDIO_VOLUME: | 749 | case V4L2_CID_AUDIO_VOLUME: |
732 | dev->volume = ctrl->value; | 750 | dev->volume = ctrl->value; |
733 | return em28xx_audio_analog_set(dev); | 751 | return em28xx_audio_analog_set(dev); |
752 | default: | ||
753 | return -EINVAL; | ||
754 | } | ||
755 | } | ||
756 | |||
757 | /*FIXME: should be moved to saa711x */ | ||
758 | static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | ||
759 | { | ||
760 | switch (ctrl->id) { | ||
734 | case V4L2_CID_BRIGHTNESS: | 761 | case V4L2_CID_BRIGHTNESS: |
735 | return em28xx_brightness_set(dev, ctrl->value); | 762 | return em28xx_brightness_set(dev, ctrl->value); |
736 | case V4L2_CID_CONTRAST: | 763 | case V4L2_CID_CONTRAST: |
@@ -994,14 +1021,34 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, | |||
994 | case VIDIOC_QUERYCTRL: | 1021 | case VIDIOC_QUERYCTRL: |
995 | { | 1022 | { |
996 | struct v4l2_queryctrl *qc = arg; | 1023 | struct v4l2_queryctrl *qc = arg; |
997 | u8 i, n; | 1024 | int i, id=qc->id; |
998 | n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); | 1025 | |
999 | for (i = 0; i < n; i++) | 1026 | memset(qc,0,sizeof(*qc)); |
1000 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | 1027 | qc->id=id; |
1001 | memcpy(qc, &(em28xx_qctrl[i]), | 1028 | |
1029 | if (!dev->has_msp34xx) { | ||
1030 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
1031 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | ||
1032 | memcpy(qc, &(em28xx_qctrl[i]), | ||
1033 | sizeof(*qc)); | ||
1034 | return 0; | ||
1035 | } | ||
1036 | } | ||
1037 | } | ||
1038 | if (dev->decoder == EM28XX_TVP5150) { | ||
1039 | em28xx_i2c_call_clients(dev,cmd,qc); | ||
1040 | if (qc->type) | ||
1041 | return 0; | ||
1042 | else | ||
1043 | return -EINVAL; | ||
1044 | } | ||
1045 | for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { | ||
1046 | if (qc->id && qc->id == saa711x_qctrl[i].id) { | ||
1047 | memcpy(qc, &(saa711x_qctrl[i]), | ||
1002 | sizeof(*qc)); | 1048 | sizeof(*qc)); |
1003 | return 0; | 1049 | return 0; |
1004 | } | 1050 | } |
1051 | } | ||
1005 | 1052 | ||
1006 | return -EINVAL; | 1053 | return -EINVAL; |
1007 | } | 1054 | } |
@@ -1009,29 +1056,64 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, | |||
1009 | case VIDIOC_G_CTRL: | 1056 | case VIDIOC_G_CTRL: |
1010 | { | 1057 | { |
1011 | struct v4l2_control *ctrl = arg; | 1058 | struct v4l2_control *ctrl = arg; |
1059 | int retval=-EINVAL; | ||
1012 | 1060 | ||
1061 | if (!dev->has_msp34xx) | ||
1062 | retval=em28xx_get_ctrl(dev, ctrl); | ||
1063 | if (retval==-EINVAL) { | ||
1064 | if (dev->decoder == EM28XX_TVP5150) { | ||
1065 | em28xx_i2c_call_clients(dev,cmd,arg); | ||
1066 | return 0; | ||
1067 | } | ||
1013 | 1068 | ||
1014 | return em28xx_get_ctrl(dev, ctrl); | 1069 | return saa711x_get_ctrl(dev, ctrl); |
1070 | } else return retval; | ||
1015 | } | 1071 | } |
1016 | 1072 | ||
1017 | case VIDIOC_S_CTRL_OLD: /* ??? */ | ||
1018 | case VIDIOC_S_CTRL: | 1073 | case VIDIOC_S_CTRL: |
1019 | { | 1074 | { |
1020 | struct v4l2_control *ctrl = arg; | 1075 | struct v4l2_control *ctrl = arg; |
1021 | u8 i, n; | 1076 | u8 i; |
1022 | 1077 | ||
1023 | 1078 | if (!dev->has_msp34xx){ | |
1024 | n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); | 1079 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { |
1025 | for (i = 0; i < n; i++) | 1080 | if (ctrl->id == em28xx_qctrl[i].id) { |
1026 | if (ctrl->id == em28xx_qctrl[i].id) { | 1081 | if (ctrl->value < |
1027 | if (ctrl->value < | 1082 | em28xx_qctrl[i].minimum |
1028 | em28xx_qctrl[i].minimum | 1083 | || ctrl->value > |
1029 | || ctrl->value > | 1084 | em28xx_qctrl[i].maximum) |
1030 | em28xx_qctrl[i].maximum) | 1085 | return -ERANGE; |
1031 | return -ERANGE; | 1086 | return em28xx_set_ctrl(dev, ctrl); |
1087 | } | ||
1088 | } | ||
1089 | } | ||
1032 | 1090 | ||
1033 | return em28xx_set_ctrl(dev, ctrl); | 1091 | if (dev->decoder == EM28XX_TVP5150) { |
1092 | em28xx_i2c_call_clients(dev,cmd,arg); | ||
1093 | return 0; | ||
1094 | } else if (!dev->has_msp34xx) { | ||
1095 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
1096 | if (ctrl->id == em28xx_qctrl[i].id) { | ||
1097 | if (ctrl->value < | ||
1098 | em28xx_qctrl[i].minimum | ||
1099 | || ctrl->value > | ||
1100 | em28xx_qctrl[i].maximum) | ||
1101 | return -ERANGE; | ||
1102 | return em28xx_set_ctrl(dev, ctrl); | ||
1103 | } | ||
1034 | } | 1104 | } |
1105 | for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { | ||
1106 | if (ctrl->id == saa711x_qctrl[i].id) { | ||
1107 | if (ctrl->value < | ||
1108 | saa711x_qctrl[i].minimum | ||
1109 | || ctrl->value > | ||
1110 | saa711x_qctrl[i].maximum) | ||
1111 | return -ERANGE; | ||
1112 | return saa711x_set_ctrl(dev, ctrl); | ||
1113 | } | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1035 | return -EINVAL; | 1117 | return -EINVAL; |
1036 | } | 1118 | } |
1037 | 1119 | ||
@@ -1187,7 +1269,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp, | |||
1187 | return -ENODEV; | 1269 | return -ENODEV; |
1188 | 1270 | ||
1189 | if (video_debug > 1) | 1271 | if (video_debug > 1) |
1190 | em28xx_print_ioctl(dev->name,cmd); | 1272 | v4l_print_ioctl(dev->name,cmd); |
1191 | 1273 | ||
1192 | switch (cmd) { | 1274 | switch (cmd) { |
1193 | 1275 | ||
@@ -1564,6 +1646,8 @@ static struct file_operations em28xx_v4l_fops = { | |||
1564 | .poll = em28xx_v4l2_poll, | 1646 | .poll = em28xx_v4l2_poll, |
1565 | .mmap = em28xx_v4l2_mmap, | 1647 | .mmap = em28xx_v4l2_mmap, |
1566 | .llseek = no_llseek, | 1648 | .llseek = no_llseek, |
1649 | .compat_ioctl = v4l_compat_ioctl32, | ||
1650 | |||
1567 | }; | 1651 | }; |
1568 | 1652 | ||
1569 | /******************************** usb interface *****************************************/ | 1653 | /******************************** usb interface *****************************************/ |
@@ -1848,9 +1932,12 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
1848 | struct em28xx *dev = usb_get_intfdata(interface); | 1932 | struct em28xx *dev = usb_get_intfdata(interface); |
1849 | usb_set_intfdata(interface, NULL); | 1933 | usb_set_intfdata(interface, NULL); |
1850 | 1934 | ||
1935 | /*FIXME: IR should be disconnected */ | ||
1936 | |||
1851 | if (!dev) | 1937 | if (!dev) |
1852 | return; | 1938 | return; |
1853 | 1939 | ||
1940 | |||
1854 | down_write(&em28xx_disconnect); | 1941 | down_write(&em28xx_disconnect); |
1855 | 1942 | ||
1856 | down(&dev->lock); | 1943 | down(&dev->lock); |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 5c7a41ce69f3..33de9d846af5 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | 2 | em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices |
3 | 3 | ||
4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | 4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> |
5 | Ludovico Cavedon <cavedon@sssup.it> | 5 | Ludovico Cavedon <cavedon@sssup.it> |
@@ -216,6 +216,8 @@ struct em28xx { | |||
216 | unsigned int has_msp34xx:1; | 216 | unsigned int has_msp34xx:1; |
217 | unsigned int has_tda9887:1; | 217 | unsigned int has_tda9887:1; |
218 | 218 | ||
219 | u32 i2s_speed; /* I2S speed for audio digital stream */ | ||
220 | |||
219 | enum em28xx_decoder decoder; | 221 | enum em28xx_decoder decoder; |
220 | 222 | ||
221 | int tuner_type; /* type of the tuner */ | 223 | int tuner_type; /* type of the tuner */ |
@@ -293,8 +295,6 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir); | |||
293 | 295 | ||
294 | /* Provided by em28xx-core.c */ | 296 | /* Provided by em28xx-core.c */ |
295 | 297 | ||
296 | void em28xx_print_ioctl(char *name, unsigned int cmd); | ||
297 | |||
298 | u32 em28xx_request_buffers(struct em28xx *dev, u32 count); | 298 | u32 em28xx_request_buffers(struct em28xx *dev, u32 count); |
299 | void em28xx_queue_unusedframes(struct em28xx *dev); | 299 | void em28xx_queue_unusedframes(struct em28xx *dev); |
300 | void em28xx_release_buffers(struct em28xx *dev); | 300 | void em28xx_release_buffers(struct em28xx *dev); |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 3cc1d6a6019b..58b0e6982822 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -279,7 +279,7 @@ static int ir_probe(struct i2c_adapter *adap); | |||
279 | 279 | ||
280 | static struct i2c_driver driver = { | 280 | static struct i2c_driver driver = { |
281 | .driver = { | 281 | .driver = { |
282 | .name = "ir remote kbd driver", | 282 | .name = "ir-kbd-i2c", |
283 | }, | 283 | }, |
284 | .id = I2C_DRIVERID_INFRARED, | 284 | .id = I2C_DRIVERID_INFRARED, |
285 | .attach_adapter = ir_probe, | 285 | .attach_adapter = ir_probe, |
@@ -304,18 +304,20 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
304 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); | 304 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); |
305 | input_dev = input_allocate_device(); | 305 | input_dev = input_allocate_device(); |
306 | if (!ir || !input_dev) { | 306 | if (!ir || !input_dev) { |
307 | kfree(ir); | ||
308 | input_free_device(input_dev); | 307 | input_free_device(input_dev); |
308 | kfree(ir); | ||
309 | return -ENOMEM; | 309 | return -ENOMEM; |
310 | } | 310 | } |
311 | memset(ir,0,sizeof(*ir)); | ||
311 | 312 | ||
312 | ir->c = client_template; | 313 | ir->c = client_template; |
313 | ir->input = input_dev; | 314 | ir->input = input_dev; |
314 | 315 | ||
315 | i2c_set_clientdata(&ir->c, ir); | ||
316 | ir->c.adapter = adap; | 316 | ir->c.adapter = adap; |
317 | ir->c.addr = addr; | 317 | ir->c.addr = addr; |
318 | 318 | ||
319 | i2c_set_clientdata(&ir->c, ir); | ||
320 | |||
319 | switch(addr) { | 321 | switch(addr) { |
320 | case 0x64: | 322 | case 0x64: |
321 | name = "Pixelview"; | 323 | name = "Pixelview"; |
@@ -378,13 +380,15 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
378 | ir->c.dev.bus_id); | 380 | ir->c.dev.bus_id); |
379 | 381 | ||
380 | /* init + register input device */ | 382 | /* init + register input device */ |
381 | ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 383 | ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes); |
382 | input_dev->id.bustype = BUS_I2C; | 384 | input_dev->id.bustype = BUS_I2C; |
383 | input_dev->name = ir->c.name; | 385 | input_dev->name = ir->c.name; |
384 | input_dev->phys = ir->phys; | 386 | input_dev->phys = ir->phys; |
385 | 387 | ||
386 | /* register event device */ | 388 | /* register event device */ |
387 | input_register_device(ir->input); | 389 | input_register_device(ir->input); |
390 | printk(DEVNAME ": %s detected at %s [%s]\n", | ||
391 | ir->input->name,ir->input->phys,adap->name); | ||
388 | 392 | ||
389 | /* start polling via eventd */ | 393 | /* start polling via eventd */ |
390 | INIT_WORK(&ir->work, ir_work, ir); | 394 | INIT_WORK(&ir->work, ir_work, ir); |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 3f2a882bc20a..2869464aee0d 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
@@ -1754,6 +1754,7 @@ static struct file_operations meye_fops = { | |||
1754 | .release = meye_release, | 1754 | .release = meye_release, |
1755 | .mmap = meye_mmap, | 1755 | .mmap = meye_mmap, |
1756 | .ioctl = meye_ioctl, | 1756 | .ioctl = meye_ioctl, |
1757 | .compat_ioctl = v4l_compat_ioctl32, | ||
1757 | .poll = meye_poll, | 1758 | .poll = meye_poll, |
1758 | .llseek = no_llseek, | 1759 | .llseek = no_llseek, |
1759 | }; | 1760 | }; |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c new file mode 100644 index 000000000000..aa8c556b6ba1 --- /dev/null +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -0,0 +1,1274 @@ | |||
1 | /* | ||
2 | * Programming the mspx4xx sound processor family | ||
3 | * | ||
4 | * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org> | ||
5 | * | ||
6 | * what works and what doesn't: | ||
7 | * | ||
8 | * AM-Mono | ||
9 | * Support for Hauppauge cards added (decoding handled by tuner) added by | ||
10 | * Frederic Crozat <fcrozat@mail.dotcom.fr> | ||
11 | * | ||
12 | * FM-Mono | ||
13 | * should work. The stereo modes are backward compatible to FM-mono, | ||
14 | * therefore FM-Mono should be allways available. | ||
15 | * | ||
16 | * FM-Stereo (B/G, used in germany) | ||
17 | * should work, with autodetect | ||
18 | * | ||
19 | * FM-Stereo (satellite) | ||
20 | * should work, no autodetect (i.e. default is mono, but you can | ||
21 | * switch to stereo -- untested) | ||
22 | * | ||
23 | * NICAM (B/G, L , used in UK, Scandinavia, Spain and France) | ||
24 | * should work, with autodetect. Support for NICAM was added by | ||
25 | * Pekka Pietikainen <pp@netppl.fi> | ||
26 | * | ||
27 | * TODO: | ||
28 | * - better SAT support | ||
29 | * | ||
30 | * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
31 | * using soundcore instead of OSS | ||
32 | * | ||
33 | * This program is free software; you can redistribute it and/or | ||
34 | * modify it under the terms of the GNU General Public License | ||
35 | * as published by the Free Software Foundation; either version 2 | ||
36 | * of the License, or (at your option) any later version. | ||
37 | * | ||
38 | * This program is distributed in the hope that it will be useful, | ||
39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
41 | * GNU General Public License for more details. | ||
42 | * | ||
43 | * You should have received a copy of the GNU General Public License | ||
44 | * along with this program; if not, write to the Free Software | ||
45 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
46 | */ | ||
47 | |||
48 | |||
49 | #include <linux/kernel.h> | ||
50 | #include <linux/module.h> | ||
51 | #include <linux/slab.h> | ||
52 | #include <linux/i2c.h> | ||
53 | #include <linux/videodev.h> | ||
54 | #include <linux/videodev2.h> | ||
55 | #include <media/v4l2-common.h> | ||
56 | #include <media/audiochip.h> | ||
57 | #include <linux/kthread.h> | ||
58 | #include <linux/suspend.h> | ||
59 | #include "msp3400.h" | ||
60 | |||
61 | /* ---------------------------------------------------------------------- */ | ||
62 | |||
63 | MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); | ||
64 | MODULE_AUTHOR("Gerd Knorr"); | ||
65 | MODULE_LICENSE("GPL"); | ||
66 | |||
67 | /* module parameters */ | ||
68 | static int opmode = OPMODE_AUTO; | ||
69 | int debug = 0; /* debug output */ | ||
70 | int once = 0; /* no continous stereo monitoring */ | ||
71 | int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), | ||
72 | the autoscan seems work well only with FM... */ | ||
73 | int standard = 1; /* Override auto detect of audio standard, if needed. */ | ||
74 | int dolby = 0; | ||
75 | |||
76 | int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual | ||
77 | (msp34xxg only) 0x00a0-0x03c0 */ | ||
78 | |||
79 | /* read-only */ | ||
80 | module_param(opmode, int, 0444); | ||
81 | |||
82 | /* read-write */ | ||
83 | module_param(once, bool, 0644); | ||
84 | module_param(debug, int, 0644); | ||
85 | module_param(stereo_threshold, int, 0644); | ||
86 | module_param(standard, int, 0644); | ||
87 | module_param(amsound, bool, 0644); | ||
88 | module_param(dolby, bool, 0644); | ||
89 | |||
90 | MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect"); | ||
91 | MODULE_PARM_DESC(once, "No continuous stereo monitoring"); | ||
92 | MODULE_PARM_DESC(debug, "Enable debug messages [0-3]"); | ||
93 | MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo"); | ||
94 | MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect"); | ||
95 | MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); | ||
96 | MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); | ||
97 | |||
98 | /* ---------------------------------------------------------------------- */ | ||
99 | |||
100 | /* control subaddress */ | ||
101 | #define I2C_MSP_CONTROL 0x00 | ||
102 | /* demodulator unit subaddress */ | ||
103 | #define I2C_MSP_DEM 0x10 | ||
104 | /* DSP unit subaddress */ | ||
105 | #define I2C_MSP_DSP 0x12 | ||
106 | |||
107 | /* Addresses to scan */ | ||
108 | static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END }; | ||
109 | I2C_CLIENT_INSMOD; | ||
110 | |||
111 | /* ----------------------------------------------------------------------- */ | ||
112 | /* functions for talking to the MSP3400C Sound processor */ | ||
113 | |||
114 | int msp_reset(struct i2c_client *client) | ||
115 | { | ||
116 | /* reset and read revision code */ | ||
117 | static u8 reset_off[3] = { I2C_MSP_CONTROL, 0x80, 0x00 }; | ||
118 | static u8 reset_on[3] = { I2C_MSP_CONTROL, 0x00, 0x00 }; | ||
119 | static u8 write[3] = { I2C_MSP_DSP + 1, 0x00, 0x1e }; | ||
120 | u8 read[2]; | ||
121 | struct i2c_msg reset[2] = { | ||
122 | { client->addr, I2C_M_IGNORE_NAK, 3, reset_off }, | ||
123 | { client->addr, I2C_M_IGNORE_NAK, 3, reset_on }, | ||
124 | }; | ||
125 | struct i2c_msg test[2] = { | ||
126 | { client->addr, 0, 3, write }, | ||
127 | { client->addr, I2C_M_RD, 2, read }, | ||
128 | }; | ||
129 | |||
130 | v4l_dbg(3, client, "msp_reset\n"); | ||
131 | if (i2c_transfer(client->adapter, &reset[0], 1) != 1 || | ||
132 | i2c_transfer(client->adapter, &reset[1], 1) != 1 || | ||
133 | i2c_transfer(client->adapter, test, 2) != 2) { | ||
134 | v4l_err(client, "chip reset failed\n"); | ||
135 | return -1; | ||
136 | } | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int msp_read(struct i2c_client *client, int dev, int addr) | ||
141 | { | ||
142 | int err, retval; | ||
143 | u8 write[3]; | ||
144 | u8 read[2]; | ||
145 | struct i2c_msg msgs[2] = { | ||
146 | { client->addr, 0, 3, write }, | ||
147 | { client->addr, I2C_M_RD, 2, read } | ||
148 | }; | ||
149 | |||
150 | write[0] = dev + 1; | ||
151 | write[1] = addr >> 8; | ||
152 | write[2] = addr & 0xff; | ||
153 | |||
154 | for (err = 0; err < 3; err++) { | ||
155 | if (i2c_transfer(client->adapter, msgs, 2) == 2) | ||
156 | break; | ||
157 | v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err, | ||
158 | dev, addr); | ||
159 | current->state = TASK_INTERRUPTIBLE; | ||
160 | schedule_timeout(msecs_to_jiffies(10)); | ||
161 | } | ||
162 | if (err == 3) { | ||
163 | v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | ||
164 | msp_reset(client); | ||
165 | return -1; | ||
166 | } | ||
167 | retval = read[0] << 8 | read[1]; | ||
168 | v4l_dbg(3, client, "msp_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); | ||
169 | return retval; | ||
170 | } | ||
171 | |||
172 | int msp_read_dem(struct i2c_client *client, int addr) | ||
173 | { | ||
174 | return msp_read(client, I2C_MSP_DEM, addr); | ||
175 | } | ||
176 | |||
177 | int msp_read_dsp(struct i2c_client *client, int addr) | ||
178 | { | ||
179 | return msp_read(client, I2C_MSP_DSP, addr); | ||
180 | } | ||
181 | |||
182 | static int msp_write(struct i2c_client *client, int dev, int addr, int val) | ||
183 | { | ||
184 | int err; | ||
185 | u8 buffer[5]; | ||
186 | |||
187 | buffer[0] = dev; | ||
188 | buffer[1] = addr >> 8; | ||
189 | buffer[2] = addr & 0xff; | ||
190 | buffer[3] = val >> 8; | ||
191 | buffer[4] = val & 0xff; | ||
192 | |||
193 | v4l_dbg(3, client, "msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); | ||
194 | for (err = 0; err < 3; err++) { | ||
195 | if (i2c_master_send(client, buffer, 5) == 5) | ||
196 | break; | ||
197 | v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err, | ||
198 | dev, addr); | ||
199 | current->state = TASK_INTERRUPTIBLE; | ||
200 | schedule_timeout(msecs_to_jiffies(10)); | ||
201 | } | ||
202 | if (err == 3) { | ||
203 | v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | ||
204 | msp_reset(client); | ||
205 | return -1; | ||
206 | } | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | int msp_write_dem(struct i2c_client *client, int addr, int val) | ||
211 | { | ||
212 | return msp_write(client, I2C_MSP_DEM, addr, val); | ||
213 | } | ||
214 | |||
215 | int msp_write_dsp(struct i2c_client *client, int addr, int val) | ||
216 | { | ||
217 | return msp_write(client, I2C_MSP_DSP, addr, val); | ||
218 | } | ||
219 | |||
220 | /* ----------------------------------------------------------------------- * | ||
221 | * bits 9 8 5 - SCART DSP input Select: | ||
222 | * 0 0 0 - SCART 1 to DSP input (reset position) | ||
223 | * 0 1 0 - MONO to DSP input | ||
224 | * 1 0 0 - SCART 2 to DSP input | ||
225 | * 1 1 1 - Mute DSP input | ||
226 | * | ||
227 | * bits 11 10 6 - SCART 1 Output Select: | ||
228 | * 0 0 0 - undefined (reset position) | ||
229 | * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) | ||
230 | * 1 0 0 - MONO input to SCART 1 Output | ||
231 | * 1 1 0 - SCART 1 DA to SCART 1 Output | ||
232 | * 0 0 1 - SCART 2 DA to SCART 1 Output | ||
233 | * 0 1 1 - SCART 1 Input to SCART 1 Output | ||
234 | * 1 1 1 - Mute SCART 1 Output | ||
235 | * | ||
236 | * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): | ||
237 | * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) | ||
238 | * 0 1 0 - SCART 1 Input to SCART 2 Output | ||
239 | * 1 0 0 - MONO input to SCART 2 Output | ||
240 | * 0 0 1 - SCART 2 DA to SCART 2 Output | ||
241 | * 0 1 1 - SCART 2 Input to SCART 2 Output | ||
242 | * 1 1 0 - Mute SCART 2 Output | ||
243 | * | ||
244 | * Bits 4 to 0 should be zero. | ||
245 | * ----------------------------------------------------------------------- */ | ||
246 | |||
247 | static int scarts[3][9] = { | ||
248 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ | ||
249 | /* SCART DSP Input select */ | ||
250 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, | ||
251 | /* SCART1 Output select */ | ||
252 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | ||
253 | /* SCART2 Output select */ | ||
254 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | ||
255 | }; | ||
256 | |||
257 | static char *scart_names[] = { | ||
258 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" | ||
259 | }; | ||
260 | |||
261 | void msp_set_scart(struct i2c_client *client, int in, int out) | ||
262 | { | ||
263 | struct msp_state *state = i2c_get_clientdata(client); | ||
264 | |||
265 | state->in_scart=in; | ||
266 | |||
267 | if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { | ||
268 | if (-1 == scarts[out][in]) | ||
269 | return; | ||
270 | |||
271 | state->acb &= ~scarts[out][SCART_MASK]; | ||
272 | state->acb |= scarts[out][in]; | ||
273 | } else | ||
274 | state->acb = 0xf60; /* Mute Input and SCART 1 Output */ | ||
275 | |||
276 | v4l_dbg(1, client, "scart switch: %s => %d (ACB=0x%04x)\n", | ||
277 | scart_names[in], out, state->acb); | ||
278 | msp_write_dsp(client, 0x13, state->acb); | ||
279 | |||
280 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | ||
281 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
282 | } | ||
283 | |||
284 | void msp_set_mute(struct i2c_client *client) | ||
285 | { | ||
286 | struct msp_state *state = i2c_get_clientdata(client); | ||
287 | |||
288 | v4l_dbg(1, client, "mute audio\n"); | ||
289 | msp_write_dsp(client, 0x0000, 0); | ||
290 | msp_write_dsp(client, 0x0007, 1); | ||
291 | if (state->has_scart2_out_volume) | ||
292 | msp_write_dsp(client, 0x0040, 1); | ||
293 | if (state->has_headphones) | ||
294 | msp_write_dsp(client, 0x0006, 0); | ||
295 | } | ||
296 | |||
297 | void msp_set_audio(struct i2c_client *client) | ||
298 | { | ||
299 | struct msp_state *state = i2c_get_clientdata(client); | ||
300 | int bal = 0, bass, treble, loudness; | ||
301 | int val = 0; | ||
302 | |||
303 | if (!state->muted) | ||
304 | val = (state->volume * 0x7f / 65535) << 8; | ||
305 | |||
306 | v4l_dbg(1, client, "mute=%s volume=%d\n", | ||
307 | state->muted ? "on" : "off", state->volume); | ||
308 | |||
309 | msp_write_dsp(client, 0x0000, val); | ||
310 | msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); | ||
311 | if (state->has_scart2_out_volume) | ||
312 | msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1)); | ||
313 | if (state->has_headphones) | ||
314 | msp_write_dsp(client, 0x0006, val); | ||
315 | if (!state->has_sound_processing) | ||
316 | return; | ||
317 | |||
318 | if (val) | ||
319 | bal = (u8)((state->balance / 256) - 128); | ||
320 | bass = ((state->bass - 32768) * 0x60 / 65535) << 8; | ||
321 | treble = ((state->treble - 32768) * 0x60 / 65535) << 8; | ||
322 | loudness = state->loudness ? ((5 * 4) << 8) : 0; | ||
323 | |||
324 | v4l_dbg(1, client, "balance=%d bass=%d treble=%d loudness=%d\n", | ||
325 | state->balance, state->bass, state->treble, state->loudness); | ||
326 | |||
327 | msp_write_dsp(client, 0x0001, bal << 8); | ||
328 | msp_write_dsp(client, 0x0002, bass); | ||
329 | msp_write_dsp(client, 0x0003, treble); | ||
330 | msp_write_dsp(client, 0x0004, loudness); | ||
331 | if (!state->has_headphones) | ||
332 | return; | ||
333 | msp_write_dsp(client, 0x0030, bal << 8); | ||
334 | msp_write_dsp(client, 0x0031, bass); | ||
335 | msp_write_dsp(client, 0x0032, treble); | ||
336 | msp_write_dsp(client, 0x0033, loudness); | ||
337 | } | ||
338 | |||
339 | int msp_modus(struct i2c_client *client) | ||
340 | { | ||
341 | struct msp_state *state = i2c_get_clientdata(client); | ||
342 | |||
343 | if (state->radio) { | ||
344 | v4l_dbg(1, client, "video mode selected to Radio\n"); | ||
345 | return 0x0003; | ||
346 | } | ||
347 | |||
348 | if (state->v4l2_std & V4L2_STD_PAL) { | ||
349 | v4l_dbg(1, client, "video mode selected to PAL\n"); | ||
350 | |||
351 | #if 1 | ||
352 | /* experimental: not sure this works with all chip versions */ | ||
353 | return 0x7003; | ||
354 | #else | ||
355 | /* previous value, try this if it breaks ... */ | ||
356 | return 0x1003; | ||
357 | #endif | ||
358 | } | ||
359 | if (state->v4l2_std & V4L2_STD_NTSC) { | ||
360 | v4l_dbg(1, client, "video mode selected to NTSC\n"); | ||
361 | return 0x2003; | ||
362 | } | ||
363 | if (state->v4l2_std & V4L2_STD_SECAM) { | ||
364 | v4l_dbg(1, client, "video mode selected to SECAM\n"); | ||
365 | return 0x0003; | ||
366 | } | ||
367 | return 0x0003; | ||
368 | } | ||
369 | |||
370 | /* ------------------------------------------------------------------------ */ | ||
371 | |||
372 | |||
373 | static void msp_wake_thread(struct i2c_client *client) | ||
374 | { | ||
375 | struct msp_state *state = i2c_get_clientdata(client); | ||
376 | |||
377 | if (NULL == state->kthread) | ||
378 | return; | ||
379 | msp_set_mute(client); | ||
380 | state->watch_stereo = 0; | ||
381 | state->restart = 1; | ||
382 | wake_up_interruptible(&state->wq); | ||
383 | } | ||
384 | |||
385 | int msp_sleep(struct msp_state *state, int timeout) | ||
386 | { | ||
387 | DECLARE_WAITQUEUE(wait, current); | ||
388 | |||
389 | add_wait_queue(&state->wq, &wait); | ||
390 | if (!kthread_should_stop()) { | ||
391 | if (timeout < 0) { | ||
392 | set_current_state(TASK_INTERRUPTIBLE); | ||
393 | schedule(); | ||
394 | } else { | ||
395 | schedule_timeout_interruptible | ||
396 | (msecs_to_jiffies(timeout)); | ||
397 | } | ||
398 | } | ||
399 | |||
400 | remove_wait_queue(&state->wq, &wait); | ||
401 | try_to_freeze(); | ||
402 | return state->restart; | ||
403 | } | ||
404 | |||
405 | /* ------------------------------------------------------------------------ */ | ||
406 | |||
407 | static int msp_mode_v4l2_to_v4l1(int rxsubchans) | ||
408 | { | ||
409 | int mode = 0; | ||
410 | |||
411 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
412 | mode |= VIDEO_SOUND_STEREO; | ||
413 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) | ||
414 | mode |= VIDEO_SOUND_LANG2; | ||
415 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | ||
416 | mode |= VIDEO_SOUND_LANG1; | ||
417 | if (mode == 0) | ||
418 | mode |= VIDEO_SOUND_MONO; | ||
419 | return mode; | ||
420 | } | ||
421 | |||
422 | static int msp_mode_v4l1_to_v4l2(int mode) | ||
423 | { | ||
424 | if (mode & VIDEO_SOUND_STEREO) | ||
425 | return V4L2_TUNER_MODE_STEREO; | ||
426 | if (mode & VIDEO_SOUND_LANG2) | ||
427 | return V4L2_TUNER_MODE_LANG2; | ||
428 | if (mode & VIDEO_SOUND_LANG1) | ||
429 | return V4L2_TUNER_MODE_LANG1; | ||
430 | return V4L2_TUNER_MODE_MONO; | ||
431 | } | ||
432 | |||
433 | static void msp_any_detect_stereo(struct i2c_client *client) | ||
434 | { | ||
435 | struct msp_state *state = i2c_get_clientdata(client); | ||
436 | |||
437 | switch (state->opmode) { | ||
438 | case OPMODE_MANUAL: | ||
439 | case OPMODE_AUTODETECT: | ||
440 | autodetect_stereo(client); | ||
441 | break; | ||
442 | case OPMODE_AUTOSELECT: | ||
443 | msp34xxg_detect_stereo(client); | ||
444 | break; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static struct v4l2_queryctrl msp_qctrl_std[] = { | ||
449 | { | ||
450 | .id = V4L2_CID_AUDIO_VOLUME, | ||
451 | .name = "Volume", | ||
452 | .minimum = 0, | ||
453 | .maximum = 65535, | ||
454 | .step = 65535/100, | ||
455 | .default_value = 58880, | ||
456 | .flags = 0, | ||
457 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
458 | },{ | ||
459 | .id = V4L2_CID_AUDIO_MUTE, | ||
460 | .name = "Mute", | ||
461 | .minimum = 0, | ||
462 | .maximum = 1, | ||
463 | .step = 1, | ||
464 | .default_value = 1, | ||
465 | .flags = 0, | ||
466 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
467 | }, | ||
468 | }; | ||
469 | |||
470 | static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { | ||
471 | { | ||
472 | .id = V4L2_CID_AUDIO_BALANCE, | ||
473 | .name = "Balance", | ||
474 | .minimum = 0, | ||
475 | .maximum = 65535, | ||
476 | .step = 65535/100, | ||
477 | .default_value = 32768, | ||
478 | .flags = 0, | ||
479 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
480 | },{ | ||
481 | .id = V4L2_CID_AUDIO_BASS, | ||
482 | .name = "Bass", | ||
483 | .minimum = 0, | ||
484 | .maximum = 65535, | ||
485 | .step = 65535/100, | ||
486 | .default_value = 32768, | ||
487 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
488 | },{ | ||
489 | .id = V4L2_CID_AUDIO_TREBLE, | ||
490 | .name = "Treble", | ||
491 | .minimum = 0, | ||
492 | .maximum = 65535, | ||
493 | .step = 65535/100, | ||
494 | .default_value = 32768, | ||
495 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
496 | },{ | ||
497 | .id = V4L2_CID_AUDIO_LOUDNESS, | ||
498 | .name = "Loudness", | ||
499 | .minimum = 0, | ||
500 | .maximum = 1, | ||
501 | .step = 1, | ||
502 | .default_value = 1, | ||
503 | .flags = 0, | ||
504 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
505 | }, | ||
506 | }; | ||
507 | |||
508 | |||
509 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) | ||
510 | { | ||
511 | struct msp_state *state = i2c_get_clientdata(client); | ||
512 | |||
513 | switch (state->opmode) { | ||
514 | case OPMODE_MANUAL: | ||
515 | case OPMODE_AUTODETECT: | ||
516 | state->watch_stereo = 0; | ||
517 | msp3400c_setstereo(client, audmode); | ||
518 | break; | ||
519 | case OPMODE_AUTOSELECT: | ||
520 | msp34xxg_set_audmode(client, audmode); | ||
521 | break; | ||
522 | } | ||
523 | } | ||
524 | |||
525 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
526 | { | ||
527 | struct msp_state *state = i2c_get_clientdata(client); | ||
528 | |||
529 | switch (ctrl->id) { | ||
530 | case V4L2_CID_AUDIO_VOLUME: | ||
531 | ctrl->value = state->volume; | ||
532 | break; | ||
533 | |||
534 | case V4L2_CID_AUDIO_MUTE: | ||
535 | ctrl->value = state->muted; | ||
536 | break; | ||
537 | |||
538 | case V4L2_CID_AUDIO_BALANCE: | ||
539 | if (!state->has_sound_processing) | ||
540 | return -EINVAL; | ||
541 | ctrl->value = state->balance; | ||
542 | break; | ||
543 | |||
544 | case V4L2_CID_AUDIO_BASS: | ||
545 | if (!state->has_sound_processing) | ||
546 | return -EINVAL; | ||
547 | ctrl->value = state->bass; | ||
548 | break; | ||
549 | |||
550 | case V4L2_CID_AUDIO_TREBLE: | ||
551 | if (!state->has_sound_processing) | ||
552 | return -EINVAL; | ||
553 | ctrl->value = state->treble; | ||
554 | break; | ||
555 | |||
556 | case V4L2_CID_AUDIO_LOUDNESS: | ||
557 | if (!state->has_sound_processing) | ||
558 | return -EINVAL; | ||
559 | ctrl->value = state->loudness; | ||
560 | break; | ||
561 | |||
562 | default: | ||
563 | return -EINVAL; | ||
564 | } | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
569 | { | ||
570 | struct msp_state *state = i2c_get_clientdata(client); | ||
571 | |||
572 | switch (ctrl->id) { | ||
573 | case V4L2_CID_AUDIO_VOLUME: | ||
574 | state->volume = ctrl->value; | ||
575 | if (state->volume == 0) | ||
576 | state->balance = 32768; | ||
577 | break; | ||
578 | |||
579 | case V4L2_CID_AUDIO_MUTE: | ||
580 | if (ctrl->value < 0 || ctrl->value >= 2) | ||
581 | return -ERANGE; | ||
582 | state->muted = ctrl->value; | ||
583 | break; | ||
584 | |||
585 | case V4L2_CID_AUDIO_BASS: | ||
586 | if (!state->has_sound_processing) | ||
587 | return -EINVAL; | ||
588 | state->bass = ctrl->value; | ||
589 | break; | ||
590 | |||
591 | case V4L2_CID_AUDIO_TREBLE: | ||
592 | if (!state->has_sound_processing) | ||
593 | return -EINVAL; | ||
594 | state->treble = ctrl->value; | ||
595 | break; | ||
596 | |||
597 | case V4L2_CID_AUDIO_LOUDNESS: | ||
598 | if (!state->has_sound_processing) | ||
599 | return -EINVAL; | ||
600 | state->loudness = ctrl->value; | ||
601 | break; | ||
602 | |||
603 | case V4L2_CID_AUDIO_BALANCE: | ||
604 | if (!state->has_sound_processing) | ||
605 | return -EINVAL; | ||
606 | state->balance = ctrl->value; | ||
607 | break; | ||
608 | |||
609 | default: | ||
610 | return -EINVAL; | ||
611 | } | ||
612 | msp_set_audio(client); | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | ||
617 | { | ||
618 | struct msp_state *state = i2c_get_clientdata(client); | ||
619 | u16 *sarg = arg; | ||
620 | int scart = 0; | ||
621 | |||
622 | if (debug >= 2) | ||
623 | v4l_i2c_print_ioctl(client, cmd); | ||
624 | |||
625 | switch (cmd) { | ||
626 | case AUDC_SET_INPUT: | ||
627 | if (*sarg == state->input) | ||
628 | break; | ||
629 | state->input = *sarg; | ||
630 | switch (*sarg) { | ||
631 | case AUDIO_RADIO: | ||
632 | /* Hauppauge uses IN2 for the radio */ | ||
633 | state->mode = MSP_MODE_FM_RADIO; | ||
634 | scart = SCART_IN2; | ||
635 | break; | ||
636 | case AUDIO_EXTERN_1: | ||
637 | /* IN1 is often used for external input ... */ | ||
638 | state->mode = MSP_MODE_EXTERN; | ||
639 | scart = SCART_IN1; | ||
640 | break; | ||
641 | case AUDIO_EXTERN_2: | ||
642 | /* ... sometimes it is IN2 through ;) */ | ||
643 | state->mode = MSP_MODE_EXTERN; | ||
644 | scart = SCART_IN2; | ||
645 | break; | ||
646 | case AUDIO_TUNER: | ||
647 | state->mode = -1; | ||
648 | break; | ||
649 | default: | ||
650 | if (*sarg & AUDIO_MUTE) | ||
651 | msp_set_scart(client, SCART_MUTE, 0); | ||
652 | break; | ||
653 | } | ||
654 | if (scart) { | ||
655 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
656 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
657 | msp_set_scart(client, scart, 0); | ||
658 | msp_write_dsp(client, 0x000d, 0x1900); | ||
659 | if (state->opmode != OPMODE_AUTOSELECT) | ||
660 | msp3400c_setstereo(client, state->audmode); | ||
661 | } | ||
662 | msp_wake_thread(client); | ||
663 | break; | ||
664 | |||
665 | case AUDC_SET_RADIO: | ||
666 | if (state->radio) | ||
667 | return 0; | ||
668 | state->radio = 1; | ||
669 | v4l_dbg(1, client, "switching to radio mode\n"); | ||
670 | state->watch_stereo = 0; | ||
671 | switch (state->opmode) { | ||
672 | case OPMODE_MANUAL: | ||
673 | /* set msp3400 to FM radio mode */ | ||
674 | msp3400c_setmode(client, MSP_MODE_FM_RADIO); | ||
675 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | ||
676 | MSP_CARRIER(10.7)); | ||
677 | msp_set_audio(client); | ||
678 | break; | ||
679 | case OPMODE_AUTODETECT: | ||
680 | case OPMODE_AUTOSELECT: | ||
681 | /* the thread will do for us */ | ||
682 | msp_wake_thread(client); | ||
683 | break; | ||
684 | } | ||
685 | break; | ||
686 | |||
687 | /* --- v4l ioctls --- */ | ||
688 | /* take care: bttv does userspace copying, we'll get a | ||
689 | kernel pointer here... */ | ||
690 | case VIDIOCGAUDIO: | ||
691 | { | ||
692 | struct video_audio *va = arg; | ||
693 | |||
694 | va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE; | ||
695 | if (state->has_sound_processing) | ||
696 | va->flags |= VIDEO_AUDIO_BALANCE | | ||
697 | VIDEO_AUDIO_BASS | | ||
698 | VIDEO_AUDIO_TREBLE; | ||
699 | if (state->muted) | ||
700 | va->flags |= VIDEO_AUDIO_MUTE; | ||
701 | va->volume = state->volume; | ||
702 | va->balance = state->volume ? state->balance : 32768; | ||
703 | va->bass = state->bass; | ||
704 | va->treble = state->treble; | ||
705 | |||
706 | if (state->radio) | ||
707 | break; | ||
708 | if (state->opmode == OPMODE_AUTOSELECT) | ||
709 | msp_any_detect_stereo(client); | ||
710 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); | ||
711 | break; | ||
712 | } | ||
713 | |||
714 | case VIDIOCSAUDIO: | ||
715 | { | ||
716 | struct video_audio *va = arg; | ||
717 | |||
718 | state->muted = (va->flags & VIDEO_AUDIO_MUTE); | ||
719 | state->volume = va->volume; | ||
720 | state->balance = va->balance; | ||
721 | state->bass = va->bass; | ||
722 | state->treble = va->treble; | ||
723 | msp_set_audio(client); | ||
724 | |||
725 | if (va->mode != 0 && state->radio == 0) | ||
726 | msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode)); | ||
727 | break; | ||
728 | } | ||
729 | |||
730 | case VIDIOCSCHAN: | ||
731 | { | ||
732 | struct video_channel *vc = arg; | ||
733 | int update = 0; | ||
734 | v4l2_std_id std; | ||
735 | |||
736 | if (state->radio) | ||
737 | update = 1; | ||
738 | state->radio = 0; | ||
739 | if (vc->norm == VIDEO_MODE_PAL) | ||
740 | std = V4L2_STD_PAL; | ||
741 | else if (vc->norm == VIDEO_MODE_SECAM) | ||
742 | std = V4L2_STD_SECAM; | ||
743 | else | ||
744 | std = V4L2_STD_NTSC; | ||
745 | if (std != state->v4l2_std) { | ||
746 | state->v4l2_std = std; | ||
747 | update = 1; | ||
748 | } | ||
749 | if (update) | ||
750 | msp_wake_thread(client); | ||
751 | break; | ||
752 | } | ||
753 | |||
754 | case VIDIOCSFREQ: | ||
755 | case VIDIOC_S_FREQUENCY: | ||
756 | { | ||
757 | /* new channel -- kick audio carrier scan */ | ||
758 | msp_wake_thread(client); | ||
759 | break; | ||
760 | } | ||
761 | |||
762 | /* msp34xx specific */ | ||
763 | case MSP_SET_MATRIX: | ||
764 | { | ||
765 | struct msp_matrix *mspm = arg; | ||
766 | |||
767 | msp_set_scart(client, mspm->input, mspm->output); | ||
768 | break; | ||
769 | } | ||
770 | |||
771 | /* --- v4l2 ioctls --- */ | ||
772 | case VIDIOC_S_STD: | ||
773 | { | ||
774 | v4l2_std_id *id = arg; | ||
775 | int update = state->radio || state->v4l2_std != *id; | ||
776 | |||
777 | state->v4l2_std = *id; | ||
778 | state->radio = 0; | ||
779 | if (update) | ||
780 | msp_wake_thread(client); | ||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | case VIDIOC_ENUMINPUT: | ||
785 | { | ||
786 | struct v4l2_input *i = arg; | ||
787 | |||
788 | if (i->index != 0) | ||
789 | return -EINVAL; | ||
790 | |||
791 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
792 | switch (i->index) { | ||
793 | case AUDIO_RADIO: | ||
794 | strcpy(i->name, "Radio"); | ||
795 | break; | ||
796 | case AUDIO_EXTERN_1: | ||
797 | strcpy(i->name, "Extern 1"); | ||
798 | break; | ||
799 | case AUDIO_EXTERN_2: | ||
800 | strcpy(i->name, "Extern 2"); | ||
801 | break; | ||
802 | case AUDIO_TUNER: | ||
803 | strcpy(i->name, "Television"); | ||
804 | break; | ||
805 | default: | ||
806 | return -EINVAL; | ||
807 | } | ||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | case VIDIOC_G_AUDIO: | ||
812 | { | ||
813 | struct v4l2_audio *a = arg; | ||
814 | |||
815 | memset(a, 0, sizeof(*a)); | ||
816 | |||
817 | switch (a->index) { | ||
818 | case AUDIO_RADIO: | ||
819 | strcpy(a->name, "Radio"); | ||
820 | break; | ||
821 | case AUDIO_EXTERN_1: | ||
822 | strcpy(a->name, "Extern 1"); | ||
823 | break; | ||
824 | case AUDIO_EXTERN_2: | ||
825 | strcpy(a->name, "Extern 2"); | ||
826 | break; | ||
827 | case AUDIO_TUNER: | ||
828 | strcpy(a->name, "Television"); | ||
829 | break; | ||
830 | default: | ||
831 | return -EINVAL; | ||
832 | } | ||
833 | |||
834 | msp_any_detect_stereo(client); | ||
835 | if (state->audmode == V4L2_TUNER_MODE_STEREO) { | ||
836 | a->capability = V4L2_AUDCAP_STEREO; | ||
837 | } | ||
838 | |||
839 | break; | ||
840 | } | ||
841 | |||
842 | case VIDIOC_S_AUDIO: | ||
843 | { | ||
844 | struct v4l2_audio *sarg = arg; | ||
845 | |||
846 | switch (sarg->index) { | ||
847 | case AUDIO_RADIO: | ||
848 | /* Hauppauge uses IN2 for the radio */ | ||
849 | state->mode = MSP_MODE_FM_RADIO; | ||
850 | scart = SCART_IN2; | ||
851 | break; | ||
852 | case AUDIO_EXTERN_1: | ||
853 | /* IN1 is often used for external input ... */ | ||
854 | state->mode = MSP_MODE_EXTERN; | ||
855 | scart = SCART_IN1; | ||
856 | break; | ||
857 | case AUDIO_EXTERN_2: | ||
858 | /* ... sometimes it is IN2 through ;) */ | ||
859 | state->mode = MSP_MODE_EXTERN; | ||
860 | scart = SCART_IN2; | ||
861 | break; | ||
862 | case AUDIO_TUNER: | ||
863 | state->mode = -1; | ||
864 | break; | ||
865 | } | ||
866 | if (scart) { | ||
867 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
868 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
869 | msp_set_scart(client, scart, 0); | ||
870 | msp_write_dsp(client, 0x000d, 0x1900); | ||
871 | } | ||
872 | if (sarg->capability == V4L2_AUDCAP_STEREO) { | ||
873 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
874 | } else { | ||
875 | state->audmode &= ~V4L2_TUNER_MODE_STEREO; | ||
876 | } | ||
877 | msp_any_set_audmode(client, state->audmode); | ||
878 | msp_wake_thread(client); | ||
879 | break; | ||
880 | } | ||
881 | |||
882 | case VIDIOC_G_TUNER: | ||
883 | { | ||
884 | struct v4l2_tuner *vt = arg; | ||
885 | |||
886 | if (state->radio) | ||
887 | break; | ||
888 | if (state->opmode == OPMODE_AUTOSELECT) | ||
889 | msp_any_detect_stereo(client); | ||
890 | vt->audmode = state->audmode; | ||
891 | vt->rxsubchans = state->rxsubchans; | ||
892 | vt->capability = V4L2_TUNER_CAP_STEREO | | ||
893 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | ||
894 | break; | ||
895 | } | ||
896 | |||
897 | case VIDIOC_S_TUNER: | ||
898 | { | ||
899 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; | ||
900 | |||
901 | if (state->radio) | ||
902 | break; | ||
903 | /* only set audmode */ | ||
904 | if (vt->audmode != -1 && vt->audmode != 0) | ||
905 | msp_any_set_audmode(client, vt->audmode); | ||
906 | break; | ||
907 | } | ||
908 | |||
909 | case VIDIOC_G_AUDOUT: | ||
910 | { | ||
911 | struct v4l2_audioout *a = (struct v4l2_audioout *)arg; | ||
912 | int idx = a->index; | ||
913 | |||
914 | memset(a, 0, sizeof(*a)); | ||
915 | |||
916 | switch (idx) { | ||
917 | case 0: | ||
918 | strcpy(a->name, "Scart1 Out"); | ||
919 | break; | ||
920 | case 1: | ||
921 | strcpy(a->name, "Scart2 Out"); | ||
922 | break; | ||
923 | case 2: | ||
924 | strcpy(a->name, "I2S Out"); | ||
925 | break; | ||
926 | default: | ||
927 | return -EINVAL; | ||
928 | } | ||
929 | break; | ||
930 | |||
931 | } | ||
932 | |||
933 | case VIDIOC_S_AUDOUT: | ||
934 | { | ||
935 | struct v4l2_audioout *a = (struct v4l2_audioout *)arg; | ||
936 | |||
937 | if (a->index < 0 || a->index > 2) | ||
938 | return -EINVAL; | ||
939 | |||
940 | v4l_dbg(1, client, "Setting audio out on msp34xx to input %i\n", a->index); | ||
941 | msp_set_scart(client, state->in_scart, a->index + 1); | ||
942 | |||
943 | break; | ||
944 | } | ||
945 | |||
946 | case VIDIOC_INT_I2S_CLOCK_FREQ: | ||
947 | { | ||
948 | u32 *a = (u32 *)arg; | ||
949 | |||
950 | v4l_dbg(1, client, "Setting I2S speed to %d\n", *a); | ||
951 | |||
952 | switch (*a) { | ||
953 | case 1024000: | ||
954 | state->i2s_mode = 0; | ||
955 | break; | ||
956 | case 2048000: | ||
957 | state->i2s_mode = 1; | ||
958 | break; | ||
959 | default: | ||
960 | return -EINVAL; | ||
961 | } | ||
962 | break; | ||
963 | } | ||
964 | |||
965 | case VIDIOC_QUERYCTRL: | ||
966 | { | ||
967 | struct v4l2_queryctrl *qc = arg; | ||
968 | int i; | ||
969 | |||
970 | for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++) | ||
971 | if (qc->id && qc->id == msp_qctrl_std[i].id) { | ||
972 | memcpy(qc, &msp_qctrl_std[i], sizeof(*qc)); | ||
973 | return 0; | ||
974 | } | ||
975 | if (!state->has_sound_processing) | ||
976 | return -EINVAL; | ||
977 | for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++) | ||
978 | if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) { | ||
979 | memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc)); | ||
980 | return 0; | ||
981 | } | ||
982 | return -EINVAL; | ||
983 | } | ||
984 | |||
985 | case VIDIOC_G_CTRL: | ||
986 | return msp_get_ctrl(client, arg); | ||
987 | |||
988 | case VIDIOC_S_CTRL: | ||
989 | return msp_set_ctrl(client, arg); | ||
990 | |||
991 | case VIDIOC_LOG_STATUS: | ||
992 | { | ||
993 | const char *p; | ||
994 | |||
995 | if (state->opmode == OPMODE_AUTOSELECT) | ||
996 | msp_any_detect_stereo(client); | ||
997 | v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", | ||
998 | client->name, state->rev1, state->rev2); | ||
999 | v4l_info(client, "Audio: volume %d%s\n", | ||
1000 | state->volume, state->muted ? " (muted)" : ""); | ||
1001 | if (state->has_sound_processing) { | ||
1002 | v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n", | ||
1003 | state->balance, state->bass, state->treble, | ||
1004 | state->loudness ? "on" : "off"); | ||
1005 | } | ||
1006 | switch (state->mode) { | ||
1007 | case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break; | ||
1008 | case MSP_MODE_FM_RADIO: p = "FM Radio"; break; | ||
1009 | case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono + FM-stereo"; break; | ||
1010 | case MSP_MODE_FM_SAT: p = "Satellite FM-mono"; break; | ||
1011 | case MSP_MODE_FM_NICAM1: p = "NICAM/FM (B/G, D/K)"; break; | ||
1012 | case MSP_MODE_FM_NICAM2: p = "NICAM/FM (I)"; break; | ||
1013 | case MSP_MODE_AM_NICAM: p = "NICAM/AM (L)"; break; | ||
1014 | case MSP_MODE_BTSC: p = "BTSC"; break; | ||
1015 | case MSP_MODE_EXTERN: p = "External input"; break; | ||
1016 | default: p = "unknown"; break; | ||
1017 | } | ||
1018 | if (state->opmode == OPMODE_MANUAL) { | ||
1019 | v4l_info(client, "Mode: %s (%s%s)\n", p, | ||
1020 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", | ||
1021 | (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); | ||
1022 | } else { | ||
1023 | v4l_info(client, "Mode: %s\n", p); | ||
1024 | v4l_info(client, "Standard: %s (%s%s)\n", | ||
1025 | msp_standard_std_name(state->std), | ||
1026 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", | ||
1027 | (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); | ||
1028 | } | ||
1029 | v4l_info(client, "ACB: 0x%04x\n", state->acb); | ||
1030 | break; | ||
1031 | } | ||
1032 | |||
1033 | default: | ||
1034 | /* nothing */ | ||
1035 | break; | ||
1036 | } | ||
1037 | return 0; | ||
1038 | } | ||
1039 | |||
1040 | static int msp_suspend(struct device * dev, pm_message_t state) | ||
1041 | { | ||
1042 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | ||
1043 | |||
1044 | v4l_dbg(1, client, "suspend\n"); | ||
1045 | msp_reset(client); | ||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | static int msp_resume(struct device * dev) | ||
1050 | { | ||
1051 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | ||
1052 | |||
1053 | v4l_dbg(1, client, "resume\n"); | ||
1054 | msp_wake_thread(client); | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | /* ----------------------------------------------------------------------- */ | ||
1059 | |||
1060 | static struct i2c_driver i2c_driver; | ||
1061 | |||
1062 | static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | ||
1063 | { | ||
1064 | struct i2c_client *client; | ||
1065 | struct msp_state *state; | ||
1066 | int (*thread_func)(void *data) = NULL; | ||
1067 | int msp_hard; | ||
1068 | int msp_family; | ||
1069 | int msp_revision; | ||
1070 | int msp_product, msp_prod_hi, msp_prod_lo; | ||
1071 | int msp_rom; | ||
1072 | |||
1073 | client = kmalloc(sizeof(*client), GFP_KERNEL); | ||
1074 | if (client == NULL) | ||
1075 | return -ENOMEM; | ||
1076 | memset(client, 0, sizeof(*client)); | ||
1077 | client->addr = address; | ||
1078 | client->adapter = adapter; | ||
1079 | client->driver = &i2c_driver; | ||
1080 | snprintf(client->name, sizeof(client->name) - 1, "msp3400"); | ||
1081 | |||
1082 | if (msp_reset(client) == -1) { | ||
1083 | v4l_dbg(1, client, "msp3400 not found\n"); | ||
1084 | kfree(client); | ||
1085 | return -1; | ||
1086 | } | ||
1087 | |||
1088 | state = kmalloc(sizeof(*state), GFP_KERNEL); | ||
1089 | if (state == NULL) { | ||
1090 | kfree(client); | ||
1091 | return -ENOMEM; | ||
1092 | } | ||
1093 | i2c_set_clientdata(client, state); | ||
1094 | |||
1095 | memset(state, 0, sizeof(*state)); | ||
1096 | state->v4l2_std = V4L2_STD_NTSC; | ||
1097 | state->volume = 58880; /* 0db gain */ | ||
1098 | state->balance = 32768; /* 0db gain */ | ||
1099 | state->bass = 32768; | ||
1100 | state->treble = 32768; | ||
1101 | state->loudness = 0; | ||
1102 | state->input = -1; | ||
1103 | state->muted = 0; | ||
1104 | state->i2s_mode = 0; | ||
1105 | init_waitqueue_head(&state->wq); | ||
1106 | |||
1107 | state->rev1 = msp_read_dsp(client, 0x1e); | ||
1108 | if (state->rev1 != -1) | ||
1109 | state->rev2 = msp_read_dsp(client, 0x1f); | ||
1110 | v4l_dbg(1, client, "rev1=0x%04x, rev2=0x%04x\n", state->rev1, state->rev2); | ||
1111 | if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) { | ||
1112 | v4l_dbg(1, client, "not an msp3400 (cannot read chip version)\n"); | ||
1113 | kfree(state); | ||
1114 | kfree(client); | ||
1115 | return -1; | ||
1116 | } | ||
1117 | |||
1118 | msp_set_audio(client); | ||
1119 | |||
1120 | msp_family = ((state->rev1 >> 4) & 0x0f) + 3; | ||
1121 | msp_product = (state->rev2 >> 8) & 0xff; | ||
1122 | msp_prod_hi = msp_product / 10; | ||
1123 | msp_prod_lo = msp_product % 10; | ||
1124 | msp_revision = (state->rev1 & 0x0f) + '@'; | ||
1125 | msp_hard = ((state->rev1 >> 8) & 0xff) + '@'; | ||
1126 | msp_rom = state->rev2 & 0x1f; | ||
1127 | snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d", | ||
1128 | msp_family, msp_product, | ||
1129 | msp_revision, msp_hard, msp_rom); | ||
1130 | |||
1131 | /* Has NICAM support: all mspx41x and mspx45x products have NICAM */ | ||
1132 | state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5; | ||
1133 | /* Has radio support: was added with revision G */ | ||
1134 | state->has_radio = msp_revision >= 'G'; | ||
1135 | /* Has headphones output: not for stripped down products */ | ||
1136 | state->has_headphones = msp_prod_lo < 5; | ||
1137 | /* Has scart4 input: not in pre D revisions, not in stripped D revs */ | ||
1138 | state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); | ||
1139 | /* Has scart2 and scart3 inputs and scart2 output: not in stripped | ||
1140 | down products of the '3' family */ | ||
1141 | state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; | ||
1142 | /* Has scart2 a volume control? Not in pre-D revisions. */ | ||
1143 | state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out; | ||
1144 | /* Has a configurable i2s out? */ | ||
1145 | state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7; | ||
1146 | /* Has subwoofer output: not in pre-D revs and not in stripped down products */ | ||
1147 | state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5; | ||
1148 | /* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in | ||
1149 | stripped down products */ | ||
1150 | state->has_sound_processing = msp_prod_lo < 7; | ||
1151 | /* Has Virtual Dolby Surround: only in msp34x1 */ | ||
1152 | state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1; | ||
1153 | /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */ | ||
1154 | state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2; | ||
1155 | |||
1156 | state->opmode = opmode; | ||
1157 | if (state->opmode == OPMODE_AUTO) { | ||
1158 | /* MSP revision G and up have both autodetect and autoselect */ | ||
1159 | if (msp_revision >= 'G') | ||
1160 | state->opmode = OPMODE_AUTOSELECT; | ||
1161 | /* MSP revision D and up have autodetect */ | ||
1162 | else if (msp_revision >= 'D') | ||
1163 | state->opmode = OPMODE_AUTODETECT; | ||
1164 | else | ||
1165 | state->opmode = OPMODE_MANUAL; | ||
1166 | } | ||
1167 | |||
1168 | /* hello world :-) */ | ||
1169 | v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name); | ||
1170 | v4l_info(client, "%s ", client->name); | ||
1171 | if (state->has_nicam && state->has_radio) | ||
1172 | printk("supports nicam and radio, "); | ||
1173 | else if (state->has_nicam) | ||
1174 | printk("supports nicam, "); | ||
1175 | else if (state->has_radio) | ||
1176 | printk("supports radio, "); | ||
1177 | printk("mode is "); | ||
1178 | |||
1179 | /* version-specific initialization */ | ||
1180 | switch (state->opmode) { | ||
1181 | case OPMODE_MANUAL: | ||
1182 | printk("manual"); | ||
1183 | thread_func = msp3400c_thread; | ||
1184 | break; | ||
1185 | case OPMODE_AUTODETECT: | ||
1186 | printk("autodetect"); | ||
1187 | thread_func = msp3410d_thread; | ||
1188 | break; | ||
1189 | case OPMODE_AUTOSELECT: | ||
1190 | printk("autodetect and autoselect"); | ||
1191 | thread_func = msp34xxg_thread; | ||
1192 | break; | ||
1193 | } | ||
1194 | printk("\n"); | ||
1195 | |||
1196 | /* startup control thread if needed */ | ||
1197 | if (thread_func) { | ||
1198 | state->kthread = kthread_run(thread_func, client, "msp34xx"); | ||
1199 | |||
1200 | if (state->kthread == NULL) | ||
1201 | v4l_warn(client, "kernel_thread() failed\n"); | ||
1202 | msp_wake_thread(client); | ||
1203 | } | ||
1204 | |||
1205 | /* done */ | ||
1206 | i2c_attach_client(client); | ||
1207 | |||
1208 | return 0; | ||
1209 | } | ||
1210 | |||
1211 | static int msp_probe(struct i2c_adapter *adapter) | ||
1212 | { | ||
1213 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
1214 | return i2c_probe(adapter, &addr_data, msp_attach); | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int msp_detach(struct i2c_client *client) | ||
1219 | { | ||
1220 | struct msp_state *state = i2c_get_clientdata(client); | ||
1221 | int err; | ||
1222 | |||
1223 | /* shutdown control thread */ | ||
1224 | if (state->kthread) { | ||
1225 | state->restart = 1; | ||
1226 | kthread_stop(state->kthread); | ||
1227 | } | ||
1228 | msp_reset(client); | ||
1229 | |||
1230 | err = i2c_detach_client(client); | ||
1231 | if (err) { | ||
1232 | return err; | ||
1233 | } | ||
1234 | |||
1235 | kfree(state); | ||
1236 | kfree(client); | ||
1237 | return 0; | ||
1238 | } | ||
1239 | |||
1240 | /* ----------------------------------------------------------------------- */ | ||
1241 | |||
1242 | /* i2c implementation */ | ||
1243 | static struct i2c_driver i2c_driver = { | ||
1244 | .id = I2C_DRIVERID_MSP3400, | ||
1245 | .attach_adapter = msp_probe, | ||
1246 | .detach_client = msp_detach, | ||
1247 | .command = msp_command, | ||
1248 | .driver = { | ||
1249 | .name = "msp3400", | ||
1250 | .suspend = msp_suspend, | ||
1251 | .resume = msp_resume, | ||
1252 | }, | ||
1253 | }; | ||
1254 | |||
1255 | static int __init msp3400_init_module(void) | ||
1256 | { | ||
1257 | return i2c_add_driver(&i2c_driver); | ||
1258 | } | ||
1259 | |||
1260 | static void __exit msp3400_cleanup_module(void) | ||
1261 | { | ||
1262 | i2c_del_driver(&i2c_driver); | ||
1263 | } | ||
1264 | |||
1265 | module_init(msp3400_init_module); | ||
1266 | module_exit(msp3400_cleanup_module); | ||
1267 | |||
1268 | /* | ||
1269 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1270 | * --------------------------------------------------------------------------- | ||
1271 | * Local variables: | ||
1272 | * c-basic-offset: 8 | ||
1273 | * End: | ||
1274 | */ | ||
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c new file mode 100644 index 000000000000..2b59b6847535 --- /dev/null +++ b/drivers/media/video/msp3400-kthreads.c | |||
@@ -0,0 +1,1010 @@ | |||
1 | /* | ||
2 | * Programming the mspx4xx sound processor family | ||
3 | * | ||
4 | * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/videodev.h> | ||
27 | #include <linux/videodev2.h> | ||
28 | #include <media/v4l2-common.h> | ||
29 | #include <media/audiochip.h> | ||
30 | #include <linux/kthread.h> | ||
31 | #include <linux/suspend.h> | ||
32 | #include "msp3400.h" | ||
33 | |||
34 | /* this one uses the automatic sound standard detection of newer msp34xx | ||
35 | chip versions */ | ||
36 | static struct { | ||
37 | int retval; | ||
38 | int main, second; | ||
39 | char *name; | ||
40 | } msp_stdlist[] = { | ||
41 | { 0x0000, 0, 0, "could not detect sound standard" }, | ||
42 | { 0x0001, 0, 0, "autodetect start" }, | ||
43 | { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" }, | ||
44 | { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" }, | ||
45 | { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, | ||
46 | { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, | ||
47 | { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, | ||
48 | { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, | ||
49 | { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, | ||
50 | { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, | ||
51 | { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, | ||
52 | { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, | ||
53 | { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, | ||
54 | { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, | ||
55 | { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, | ||
56 | { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" }, | ||
57 | { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" }, | ||
58 | { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" }, | ||
59 | { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" }, | ||
60 | { -1, 0, 0, NULL }, /* EOF */ | ||
61 | }; | ||
62 | |||
63 | static struct msp3400c_init_data_dem { | ||
64 | int fir1[6]; | ||
65 | int fir2[6]; | ||
66 | int cdo1; | ||
67 | int cdo2; | ||
68 | int ad_cv; | ||
69 | int mode_reg; | ||
70 | int dsp_src; | ||
71 | int dsp_matrix; | ||
72 | } msp3400c_init_data[] = { | ||
73 | { /* AM (for carrier detect / msp3400) */ | ||
74 | {75, 19, 36, 35, 39, 40}, | ||
75 | {75, 19, 36, 35, 39, 40}, | ||
76 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
77 | 0x00d0, 0x0500, 0x0020, 0x3000 | ||
78 | },{ /* AM (for carrier detect / msp3410) */ | ||
79 | {-1, -1, -8, 2, 59, 126}, | ||
80 | {-1, -1, -8, 2, 59, 126}, | ||
81 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
82 | 0x00d0, 0x0100, 0x0020, 0x3000 | ||
83 | },{ /* FM Radio */ | ||
84 | {-8, -8, 4, 6, 78, 107}, | ||
85 | {-8, -8, 4, 6, 78, 107}, | ||
86 | MSP_CARRIER(10.7), MSP_CARRIER(10.7), | ||
87 | 0x00d0, 0x0480, 0x0020, 0x3000 | ||
88 | },{ /* Terrestial FM-mono + FM-stereo */ | ||
89 | {3, 18, 27, 48, 66, 72}, | ||
90 | {3, 18, 27, 48, 66, 72}, | ||
91 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
92 | 0x00d0, 0x0480, 0x0030, 0x3000 | ||
93 | },{ /* Sat FM-mono */ | ||
94 | { 1, 9, 14, 24, 33, 37}, | ||
95 | { 3, 18, 27, 48, 66, 72}, | ||
96 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | ||
97 | 0x00c6, 0x0480, 0x0000, 0x3000 | ||
98 | },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ | ||
99 | {-2, -8, -10, 10, 50, 86}, | ||
100 | {3, 18, 27, 48, 66, 72}, | ||
101 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
102 | 0x00d0, 0x0040, 0x0120, 0x3000 | ||
103 | },{ /* NICAM/FM -- I (6.0/6.552) */ | ||
104 | {2, 4, -6, -4, 40, 94}, | ||
105 | {3, 18, 27, 48, 66, 72}, | ||
106 | MSP_CARRIER(6.0), MSP_CARRIER(6.0), | ||
107 | 0x00d0, 0x0040, 0x0120, 0x3000 | ||
108 | },{ /* NICAM/AM -- L (6.5/5.85) */ | ||
109 | {-2, -8, -10, 10, 50, 86}, | ||
110 | {-4, -12, -9, 23, 79, 126}, | ||
111 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | ||
112 | 0x00c6, 0x0140, 0x0120, 0x7c03 | ||
113 | }, | ||
114 | }; | ||
115 | |||
116 | struct msp3400c_carrier_detect { | ||
117 | int cdo; | ||
118 | char *name; | ||
119 | }; | ||
120 | |||
121 | static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = { | ||
122 | /* main carrier */ | ||
123 | { MSP_CARRIER(4.5), "4.5 NTSC" }, | ||
124 | { MSP_CARRIER(5.5), "5.5 PAL B/G" }, | ||
125 | { MSP_CARRIER(6.0), "6.0 PAL I" }, | ||
126 | { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } | ||
127 | }; | ||
128 | |||
129 | static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = { | ||
130 | /* PAL B/G */ | ||
131 | { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, | ||
132 | { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } | ||
133 | }; | ||
134 | |||
135 | static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = { | ||
136 | /* PAL SAT / SECAM */ | ||
137 | { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, | ||
138 | { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, | ||
139 | { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" }, | ||
140 | { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" }, | ||
141 | { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" }, | ||
142 | { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, | ||
143 | }; | ||
144 | |||
145 | /* ------------------------------------------------------------------------ */ | ||
146 | |||
147 | const char *msp_standard_std_name(int std) | ||
148 | { | ||
149 | int i; | ||
150 | |||
151 | for (i = 0; msp_stdlist[i].name != NULL; i++) | ||
152 | if (msp_stdlist[i].retval == std) | ||
153 | return msp_stdlist[i].name; | ||
154 | return "unknown"; | ||
155 | } | ||
156 | |||
157 | void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | ||
158 | { | ||
159 | msp_write_dem(client, 0x0093, cdo1 & 0xfff); | ||
160 | msp_write_dem(client, 0x009b, cdo1 >> 12); | ||
161 | msp_write_dem(client, 0x00a3, cdo2 & 0xfff); | ||
162 | msp_write_dem(client, 0x00ab, cdo2 >> 12); | ||
163 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ | ||
164 | } | ||
165 | |||
166 | void msp3400c_setmode(struct i2c_client *client, int type) | ||
167 | { | ||
168 | struct msp_state *state = i2c_get_clientdata(client); | ||
169 | int i; | ||
170 | |||
171 | v4l_dbg(1, client, "setmode: %d\n", type); | ||
172 | state->mode = type; | ||
173 | state->audmode = V4L2_TUNER_MODE_MONO; | ||
174 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
175 | |||
176 | msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv); | ||
177 | |||
178 | for (i = 5; i >= 0; i--) /* fir 1 */ | ||
179 | msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]); | ||
180 | |||
181 | msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ | ||
182 | msp_write_dem(client, 0x0005, 0x0040); | ||
183 | msp_write_dem(client, 0x0005, 0x0000); | ||
184 | for (i = 5; i >= 0; i--) | ||
185 | msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]); | ||
186 | |||
187 | msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg); | ||
188 | |||
189 | msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1, | ||
190 | msp3400c_init_data[type].cdo2); | ||
191 | |||
192 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ | ||
193 | |||
194 | if (dolby) { | ||
195 | msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ | ||
196 | msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ | ||
197 | msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); | ||
198 | } else { | ||
199 | msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src); | ||
200 | msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src); | ||
201 | msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); | ||
202 | } | ||
203 | msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src); | ||
204 | msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix); | ||
205 | |||
206 | if (state->has_nicam) { | ||
207 | /* nicam prescale */ | ||
208 | msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */ | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* turn on/off nicam + stereo */ | ||
213 | void msp3400c_setstereo(struct i2c_client *client, int mode) | ||
214 | { | ||
215 | static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; | ||
216 | struct msp_state *state = i2c_get_clientdata(client); | ||
217 | int nicam = 0; /* channel source: FM/AM or nicam */ | ||
218 | int src = 0; | ||
219 | |||
220 | if (state->opmode == OPMODE_AUTOSELECT) { | ||
221 | /* this method would break everything, let's make sure | ||
222 | * it's never called | ||
223 | */ | ||
224 | v4l_dbg(1, client, "setstereo called with mode=%d instead of set_source (ignored)\n", | ||
225 | mode); | ||
226 | return; | ||
227 | } | ||
228 | |||
229 | /* switch demodulator */ | ||
230 | switch (state->mode) { | ||
231 | case MSP_MODE_FM_TERRA: | ||
232 | v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]); | ||
233 | msp3400c_setcarrier(client, state->second, state->main); | ||
234 | switch (mode) { | ||
235 | case V4L2_TUNER_MODE_STEREO: | ||
236 | msp_write_dsp(client, 0x000e, 0x3001); | ||
237 | break; | ||
238 | case V4L2_TUNER_MODE_MONO: | ||
239 | case V4L2_TUNER_MODE_LANG1: | ||
240 | case V4L2_TUNER_MODE_LANG2: | ||
241 | msp_write_dsp(client, 0x000e, 0x3000); | ||
242 | break; | ||
243 | } | ||
244 | break; | ||
245 | case MSP_MODE_FM_SAT: | ||
246 | v4l_dbg(1, client, "SAT setstereo: %s\n", strmode[mode]); | ||
247 | switch (mode) { | ||
248 | case V4L2_TUNER_MODE_MONO: | ||
249 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); | ||
250 | break; | ||
251 | case V4L2_TUNER_MODE_STEREO: | ||
252 | msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); | ||
253 | break; | ||
254 | case V4L2_TUNER_MODE_LANG1: | ||
255 | msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); | ||
256 | break; | ||
257 | case V4L2_TUNER_MODE_LANG2: | ||
258 | msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); | ||
259 | break; | ||
260 | } | ||
261 | break; | ||
262 | case MSP_MODE_FM_NICAM1: | ||
263 | case MSP_MODE_FM_NICAM2: | ||
264 | case MSP_MODE_AM_NICAM: | ||
265 | v4l_dbg(1, client, "NICAM setstereo: %s\n",strmode[mode]); | ||
266 | msp3400c_setcarrier(client,state->second,state->main); | ||
267 | if (state->nicam_on) | ||
268 | nicam=0x0100; | ||
269 | break; | ||
270 | case MSP_MODE_BTSC: | ||
271 | v4l_dbg(1, client, "BTSC setstereo: %s\n",strmode[mode]); | ||
272 | nicam=0x0300; | ||
273 | break; | ||
274 | case MSP_MODE_EXTERN: | ||
275 | v4l_dbg(1, client, "extern setstereo: %s\n",strmode[mode]); | ||
276 | nicam = 0x0200; | ||
277 | break; | ||
278 | case MSP_MODE_FM_RADIO: | ||
279 | v4l_dbg(1, client, "FM-Radio setstereo: %s\n",strmode[mode]); | ||
280 | break; | ||
281 | default: | ||
282 | v4l_dbg(1, client, "mono setstereo\n"); | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | /* switch audio */ | ||
287 | switch (mode) { | ||
288 | case V4L2_TUNER_MODE_STEREO: | ||
289 | src = 0x0020 | nicam; | ||
290 | break; | ||
291 | case V4L2_TUNER_MODE_MONO: | ||
292 | if (state->mode == MSP_MODE_AM_NICAM) { | ||
293 | v4l_dbg(1, client, "switching to AM mono\n"); | ||
294 | /* AM mono decoding is handled by tuner, not MSP chip */ | ||
295 | /* SCART switching control register */ | ||
296 | msp_set_scart(client, SCART_MONO, 0); | ||
297 | src = 0x0200; | ||
298 | break; | ||
299 | } | ||
300 | case V4L2_TUNER_MODE_LANG1: | ||
301 | src = 0x0000 | nicam; | ||
302 | break; | ||
303 | case V4L2_TUNER_MODE_LANG2: | ||
304 | src = 0x0010 | nicam; | ||
305 | break; | ||
306 | } | ||
307 | v4l_dbg(1, client, "setstereo final source/matrix = 0x%x\n", src); | ||
308 | |||
309 | if (dolby) { | ||
310 | msp_write_dsp(client, 0x0008, 0x0520); | ||
311 | msp_write_dsp(client, 0x0009, 0x0620); | ||
312 | msp_write_dsp(client, 0x000a, src); | ||
313 | msp_write_dsp(client, 0x000b, src); | ||
314 | } else { | ||
315 | msp_write_dsp(client, 0x0008, src); | ||
316 | msp_write_dsp(client, 0x0009, src); | ||
317 | msp_write_dsp(client, 0x000a, src); | ||
318 | msp_write_dsp(client, 0x000b, src); | ||
319 | msp_write_dsp(client, 0x000c, src); | ||
320 | if (state->has_scart23_in_scart2_out) | ||
321 | msp_write_dsp(client, 0x0041, src); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | static void msp3400c_print_mode(struct i2c_client *client) | ||
326 | { | ||
327 | struct msp_state *state = i2c_get_clientdata(client); | ||
328 | |||
329 | if (state->main == state->second) { | ||
330 | v4l_dbg(1, client, "mono sound carrier: %d.%03d MHz\n", | ||
331 | state->main / 910000, (state->main / 910) % 1000); | ||
332 | } else { | ||
333 | v4l_dbg(1, client, "main sound carrier: %d.%03d MHz\n", | ||
334 | state->main / 910000, (state->main / 910) % 1000); | ||
335 | } | ||
336 | if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2) | ||
337 | v4l_dbg(1, client, "NICAM/FM carrier : %d.%03d MHz\n", | ||
338 | state->second / 910000, (state->second/910) % 1000); | ||
339 | if (state->mode == MSP_MODE_AM_NICAM) | ||
340 | v4l_dbg(1, client, "NICAM/AM carrier : %d.%03d MHz\n", | ||
341 | state->second / 910000, (state->second / 910) % 1000); | ||
342 | if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) { | ||
343 | v4l_dbg(1, client, "FM-stereo carrier : %d.%03d MHz\n", | ||
344 | state->second / 910000, (state->second / 910) % 1000); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /* ----------------------------------------------------------------------- */ | ||
349 | |||
350 | int autodetect_stereo(struct i2c_client *client) | ||
351 | { | ||
352 | struct msp_state *state = i2c_get_clientdata(client); | ||
353 | int val; | ||
354 | int rxsubchans = state->rxsubchans; | ||
355 | int newnicam = state->nicam_on; | ||
356 | int update = 0; | ||
357 | |||
358 | switch (state->mode) { | ||
359 | case MSP_MODE_FM_TERRA: | ||
360 | val = msp_read_dsp(client, 0x18); | ||
361 | if (val > 32767) | ||
362 | val -= 65536; | ||
363 | v4l_dbg(2, client, "stereo detect register: %d\n", val); | ||
364 | if (val > 4096) { | ||
365 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | ||
366 | } else if (val < -4096) { | ||
367 | rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
368 | } else { | ||
369 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
370 | } | ||
371 | newnicam = 0; | ||
372 | break; | ||
373 | case MSP_MODE_FM_NICAM1: | ||
374 | case MSP_MODE_FM_NICAM2: | ||
375 | case MSP_MODE_AM_NICAM: | ||
376 | val = msp_read_dem(client, 0x23); | ||
377 | v4l_dbg(2, client, "nicam sync=%d, mode=%d\n", | ||
378 | val & 1, (val & 0x1e) >> 1); | ||
379 | |||
380 | if (val & 1) { | ||
381 | /* nicam synced */ | ||
382 | switch ((val & 0x1e) >> 1) { | ||
383 | case 0: | ||
384 | case 8: | ||
385 | rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
386 | break; | ||
387 | case 1: | ||
388 | case 9: | ||
389 | rxsubchans = V4L2_TUNER_SUB_MONO | ||
390 | | V4L2_TUNER_SUB_LANG1; | ||
391 | break; | ||
392 | case 2: | ||
393 | case 10: | ||
394 | rxsubchans = V4L2_TUNER_SUB_MONO | ||
395 | | V4L2_TUNER_SUB_LANG1 | ||
396 | | V4L2_TUNER_SUB_LANG2; | ||
397 | break; | ||
398 | default: | ||
399 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
400 | break; | ||
401 | } | ||
402 | newnicam = 1; | ||
403 | } else { | ||
404 | newnicam = 0; | ||
405 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
406 | } | ||
407 | break; | ||
408 | case MSP_MODE_BTSC: | ||
409 | val = msp_read_dem(client, 0x200); | ||
410 | v4l_dbg(2, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n", | ||
411 | val, | ||
412 | (val & 0x0002) ? "no" : "yes", | ||
413 | (val & 0x0004) ? "no" : "yes", | ||
414 | (val & 0x0040) ? "stereo" : "mono", | ||
415 | (val & 0x0080) ? ", nicam 2nd mono" : "", | ||
416 | (val & 0x0100) ? ", bilingual/SAP" : ""); | ||
417 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
418 | if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
419 | if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; | ||
420 | break; | ||
421 | } | ||
422 | if (rxsubchans != state->rxsubchans) { | ||
423 | update = 1; | ||
424 | v4l_dbg(1, client, "watch: rxsubchans %d => %d\n", | ||
425 | state->rxsubchans,rxsubchans); | ||
426 | state->rxsubchans = rxsubchans; | ||
427 | } | ||
428 | if (newnicam != state->nicam_on) { | ||
429 | update = 1; | ||
430 | v4l_dbg(1, client, "watch: nicam %d => %d\n", | ||
431 | state->nicam_on,newnicam); | ||
432 | state->nicam_on = newnicam; | ||
433 | } | ||
434 | return update; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * A kernel thread for msp3400 control -- we don't want to block the | ||
439 | * in the ioctl while doing the sound carrier & stereo detect | ||
440 | */ | ||
441 | /* stereo/multilang monitoring */ | ||
442 | static void watch_stereo(struct i2c_client *client) | ||
443 | { | ||
444 | struct msp_state *state = i2c_get_clientdata(client); | ||
445 | |||
446 | if (autodetect_stereo(client)) { | ||
447 | if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
448 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); | ||
449 | else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1) | ||
450 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); | ||
451 | else | ||
452 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
453 | } | ||
454 | |||
455 | if (once) | ||
456 | state->watch_stereo = 0; | ||
457 | } | ||
458 | |||
459 | int msp3400c_thread(void *data) | ||
460 | { | ||
461 | struct i2c_client *client = data; | ||
462 | struct msp_state *state = i2c_get_clientdata(client); | ||
463 | struct msp3400c_carrier_detect *cd; | ||
464 | int count, max1,max2,val1,val2, val,this; | ||
465 | |||
466 | |||
467 | v4l_dbg(1, client, "msp3400 daemon started\n"); | ||
468 | for (;;) { | ||
469 | v4l_dbg(2, client, "msp3400 thread: sleep\n"); | ||
470 | msp_sleep(state, -1); | ||
471 | v4l_dbg(2, client, "msp3400 thread: wakeup\n"); | ||
472 | |||
473 | restart: | ||
474 | v4l_dbg(1, client, "thread: restart scan\n"); | ||
475 | state->restart = 0; | ||
476 | if (kthread_should_stop()) | ||
477 | break; | ||
478 | |||
479 | if (state->radio || MSP_MODE_EXTERN == state->mode) { | ||
480 | /* no carrier scan, just unmute */ | ||
481 | v4l_dbg(1, client, "thread: no carrier scan\n"); | ||
482 | msp_set_audio(client); | ||
483 | continue; | ||
484 | } | ||
485 | |||
486 | /* mute */ | ||
487 | msp_set_mute(client); | ||
488 | msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); | ||
489 | val1 = val2 = 0; | ||
490 | max1 = max2 = -1; | ||
491 | state->watch_stereo = 0; | ||
492 | |||
493 | /* some time for the tuner to sync */ | ||
494 | if (msp_sleep(state,200)) | ||
495 | goto restart; | ||
496 | |||
497 | /* carrier detect pass #1 -- main carrier */ | ||
498 | cd = msp3400c_carrier_detect_main; | ||
499 | count = ARRAY_SIZE(msp3400c_carrier_detect_main); | ||
500 | |||
501 | if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) { | ||
502 | /* autodetect doesn't work well with AM ... */ | ||
503 | max1 = 3; | ||
504 | count = 0; | ||
505 | v4l_dbg(1, client, "AM sound override\n"); | ||
506 | } | ||
507 | |||
508 | for (this = 0; this < count; this++) { | ||
509 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | ||
510 | if (msp_sleep(state,100)) | ||
511 | goto restart; | ||
512 | val = msp_read_dsp(client, 0x1b); | ||
513 | if (val > 32767) | ||
514 | val -= 65536; | ||
515 | if (val1 < val) | ||
516 | val1 = val, max1 = this; | ||
517 | v4l_dbg(1, client, "carrier1 val: %5d / %s\n", val,cd[this].name); | ||
518 | } | ||
519 | |||
520 | /* carrier detect pass #2 -- second (stereo) carrier */ | ||
521 | switch (max1) { | ||
522 | case 1: /* 5.5 */ | ||
523 | cd = msp3400c_carrier_detect_55; | ||
524 | count = ARRAY_SIZE(msp3400c_carrier_detect_55); | ||
525 | break; | ||
526 | case 3: /* 6.5 */ | ||
527 | cd = msp3400c_carrier_detect_65; | ||
528 | count = ARRAY_SIZE(msp3400c_carrier_detect_65); | ||
529 | break; | ||
530 | case 0: /* 4.5 */ | ||
531 | case 2: /* 6.0 */ | ||
532 | default: | ||
533 | cd = NULL; | ||
534 | count = 0; | ||
535 | break; | ||
536 | } | ||
537 | |||
538 | if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) { | ||
539 | /* autodetect doesn't work well with AM ... */ | ||
540 | cd = NULL; | ||
541 | count = 0; | ||
542 | max2 = 0; | ||
543 | } | ||
544 | for (this = 0; this < count; this++) { | ||
545 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | ||
546 | if (msp_sleep(state,100)) | ||
547 | goto restart; | ||
548 | val = msp_read_dsp(client, 0x1b); | ||
549 | if (val > 32767) | ||
550 | val -= 65536; | ||
551 | if (val2 < val) | ||
552 | val2 = val, max2 = this; | ||
553 | v4l_dbg(1, client, "carrier2 val: %5d / %s\n", val,cd[this].name); | ||
554 | } | ||
555 | |||
556 | /* program the msp3400 according to the results */ | ||
557 | state->main = msp3400c_carrier_detect_main[max1].cdo; | ||
558 | switch (max1) { | ||
559 | case 1: /* 5.5 */ | ||
560 | if (max2 == 0) { | ||
561 | /* B/G FM-stereo */ | ||
562 | state->second = msp3400c_carrier_detect_55[max2].cdo; | ||
563 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | ||
564 | state->nicam_on = 0; | ||
565 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
566 | state->watch_stereo = 1; | ||
567 | } else if (max2 == 1 && state->has_nicam) { | ||
568 | /* B/G NICAM */ | ||
569 | state->second = msp3400c_carrier_detect_55[max2].cdo; | ||
570 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | ||
571 | state->nicam_on = 1; | ||
572 | msp3400c_setcarrier(client, state->second, state->main); | ||
573 | state->watch_stereo = 1; | ||
574 | } else { | ||
575 | goto no_second; | ||
576 | } | ||
577 | break; | ||
578 | case 2: /* 6.0 */ | ||
579 | /* PAL I NICAM */ | ||
580 | state->second = MSP_CARRIER(6.552); | ||
581 | msp3400c_setmode(client, MSP_MODE_FM_NICAM2); | ||
582 | state->nicam_on = 1; | ||
583 | msp3400c_setcarrier(client, state->second, state->main); | ||
584 | state->watch_stereo = 1; | ||
585 | break; | ||
586 | case 3: /* 6.5 */ | ||
587 | if (max2 == 1 || max2 == 2) { | ||
588 | /* D/K FM-stereo */ | ||
589 | state->second = msp3400c_carrier_detect_65[max2].cdo; | ||
590 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | ||
591 | state->nicam_on = 0; | ||
592 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
593 | state->watch_stereo = 1; | ||
594 | } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) { | ||
595 | /* L NICAM or AM-mono */ | ||
596 | state->second = msp3400c_carrier_detect_65[max2].cdo; | ||
597 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); | ||
598 | state->nicam_on = 0; | ||
599 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
600 | msp3400c_setcarrier(client, state->second, state->main); | ||
601 | /* volume prescale for SCART (AM mono input) */ | ||
602 | msp_write_dsp(client, 0x000d, 0x1900); | ||
603 | state->watch_stereo = 1; | ||
604 | } else if (max2 == 0 && state->has_nicam) { | ||
605 | /* D/K NICAM */ | ||
606 | state->second = msp3400c_carrier_detect_65[max2].cdo; | ||
607 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | ||
608 | state->nicam_on = 1; | ||
609 | msp3400c_setcarrier(client, state->second, state->main); | ||
610 | state->watch_stereo = 1; | ||
611 | } else { | ||
612 | goto no_second; | ||
613 | } | ||
614 | break; | ||
615 | case 0: /* 4.5 */ | ||
616 | default: | ||
617 | no_second: | ||
618 | state->second = msp3400c_carrier_detect_main[max1].cdo; | ||
619 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | ||
620 | state->nicam_on = 0; | ||
621 | msp3400c_setcarrier(client, state->second, state->main); | ||
622 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
623 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
624 | break; | ||
625 | } | ||
626 | |||
627 | /* unmute */ | ||
628 | msp_set_audio(client); | ||
629 | |||
630 | if (debug) | ||
631 | msp3400c_print_mode(client); | ||
632 | |||
633 | /* monitor tv audio mode */ | ||
634 | while (state->watch_stereo) { | ||
635 | if (msp_sleep(state,5000)) | ||
636 | goto restart; | ||
637 | watch_stereo(client); | ||
638 | } | ||
639 | } | ||
640 | v4l_dbg(1, client, "thread: exit\n"); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | |||
645 | int msp3410d_thread(void *data) | ||
646 | { | ||
647 | struct i2c_client *client = data; | ||
648 | struct msp_state *state = i2c_get_clientdata(client); | ||
649 | int val, i, std; | ||
650 | |||
651 | v4l_dbg(1, client, "msp3410 daemon started\n"); | ||
652 | |||
653 | for (;;) { | ||
654 | v4l_dbg(2, client, "msp3410 thread: sleep\n"); | ||
655 | msp_sleep(state,-1); | ||
656 | v4l_dbg(2, client, "msp3410 thread: wakeup\n"); | ||
657 | |||
658 | restart: | ||
659 | v4l_dbg(1, client, "thread: restart scan\n"); | ||
660 | state->restart = 0; | ||
661 | if (kthread_should_stop()) | ||
662 | break; | ||
663 | |||
664 | if (state->mode == MSP_MODE_EXTERN) { | ||
665 | /* no carrier scan needed, just unmute */ | ||
666 | v4l_dbg(1, client, "thread: no carrier scan\n"); | ||
667 | msp_set_audio(client); | ||
668 | continue; | ||
669 | } | ||
670 | |||
671 | /* put into sane state (and mute) */ | ||
672 | msp_reset(client); | ||
673 | |||
674 | /* some time for the tuner to sync */ | ||
675 | if (msp_sleep(state,200)) | ||
676 | goto restart; | ||
677 | |||
678 | /* start autodetect */ | ||
679 | if (state->radio) | ||
680 | std = 0x40; | ||
681 | else | ||
682 | std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; | ||
683 | state->watch_stereo = 0; | ||
684 | |||
685 | if (debug) | ||
686 | v4l_dbg(1, client, "setting standard: %s (0x%04x)\n", | ||
687 | msp_standard_std_name(std), std); | ||
688 | |||
689 | if (std != 1) { | ||
690 | /* programmed some specific mode */ | ||
691 | val = std; | ||
692 | } else { | ||
693 | /* triggered autodetect */ | ||
694 | msp_write_dem(client, 0x20, std); | ||
695 | for (;;) { | ||
696 | if (msp_sleep(state, 100)) | ||
697 | goto restart; | ||
698 | |||
699 | /* check results */ | ||
700 | val = msp_read_dem(client, 0x7e); | ||
701 | if (val < 0x07ff) | ||
702 | break; | ||
703 | v4l_dbg(1, client, "detection still in progress\n"); | ||
704 | } | ||
705 | } | ||
706 | for (i = 0; msp_stdlist[i].name != NULL; i++) | ||
707 | if (msp_stdlist[i].retval == val) | ||
708 | break; | ||
709 | v4l_dbg(1, client, "current standard: %s (0x%04x)\n", | ||
710 | msp_standard_std_name(val), val); | ||
711 | state->main = msp_stdlist[i].main; | ||
712 | state->second = msp_stdlist[i].second; | ||
713 | state->std = val; | ||
714 | |||
715 | if (amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) && | ||
716 | (val != 0x0009)) { | ||
717 | /* autodetection has failed, let backup */ | ||
718 | v4l_dbg(1, client, "autodetection failed," | ||
719 | " switching to backup standard: %s (0x%04x)\n", | ||
720 | msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val); | ||
721 | val = 0x0009; | ||
722 | msp_write_dem(client, 0x20, val); | ||
723 | } | ||
724 | |||
725 | /* set various prescales */ | ||
726 | msp_write_dsp(client, 0x0d, 0x1900); /* scart */ | ||
727 | msp_write_dsp(client, 0x0e, 0x2403); /* FM */ | ||
728 | msp_write_dsp(client, 0x10, 0x5a00); /* nicam */ | ||
729 | |||
730 | /* set stereo */ | ||
731 | switch (val) { | ||
732 | case 0x0008: /* B/G NICAM */ | ||
733 | case 0x000a: /* I NICAM */ | ||
734 | if (val == 0x0008) | ||
735 | state->mode = MSP_MODE_FM_NICAM1; | ||
736 | else | ||
737 | state->mode = MSP_MODE_FM_NICAM2; | ||
738 | /* just turn on stereo */ | ||
739 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
740 | state->nicam_on = 1; | ||
741 | state->watch_stereo = 1; | ||
742 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); | ||
743 | break; | ||
744 | case 0x0009: | ||
745 | state->mode = MSP_MODE_AM_NICAM; | ||
746 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
747 | state->nicam_on = 1; | ||
748 | msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); | ||
749 | state->watch_stereo = 1; | ||
750 | break; | ||
751 | case 0x0020: /* BTSC */ | ||
752 | /* just turn on stereo */ | ||
753 | state->mode = MSP_MODE_BTSC; | ||
754 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
755 | state->nicam_on = 0; | ||
756 | state->watch_stereo = 1; | ||
757 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); | ||
758 | break; | ||
759 | case 0x0040: /* FM radio */ | ||
760 | state->mode = MSP_MODE_FM_RADIO; | ||
761 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
762 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
763 | state->nicam_on = 0; | ||
764 | state->watch_stereo = 0; | ||
765 | /* not needed in theory if we have radio, but | ||
766 | short programming enables carrier mute */ | ||
767 | msp3400c_setmode(client, MSP_MODE_FM_RADIO); | ||
768 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | ||
769 | MSP_CARRIER(10.7)); | ||
770 | /* scart routing */ | ||
771 | msp_set_scart(client,SCART_IN2,0); | ||
772 | /* msp34xx does radio decoding */ | ||
773 | msp_write_dsp(client, 0x08, 0x0020); | ||
774 | msp_write_dsp(client, 0x09, 0x0020); | ||
775 | msp_write_dsp(client, 0x0b, 0x0020); | ||
776 | break; | ||
777 | case 0x0003: | ||
778 | case 0x0004: | ||
779 | case 0x0005: | ||
780 | state->mode = MSP_MODE_FM_TERRA; | ||
781 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
782 | state->audmode = V4L2_TUNER_MODE_MONO; | ||
783 | state->nicam_on = 0; | ||
784 | state->watch_stereo = 1; | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | /* unmute, restore misc registers */ | ||
789 | msp_set_audio(client); | ||
790 | msp_write_dsp(client, 0x13, state->acb); | ||
791 | if (state->has_i2s_conf) | ||
792 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
793 | |||
794 | /* monitor tv audio mode */ | ||
795 | while (state->watch_stereo) { | ||
796 | if (msp_sleep(state,5000)) | ||
797 | goto restart; | ||
798 | watch_stereo(client); | ||
799 | } | ||
800 | } | ||
801 | v4l_dbg(1, client, "thread: exit\n"); | ||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | /* ----------------------------------------------------------------------- */ | ||
806 | |||
807 | /* msp34xxG + (autoselect no-thread) */ | ||
808 | /* this one uses both automatic standard detection and automatic sound */ | ||
809 | /* select which are available in the newer G versions */ | ||
810 | /* struct msp: only norm, acb and source are really used in this mode */ | ||
811 | |||
812 | /* set the same 'source' for the loudspeaker, scart and quasi-peak detector | ||
813 | * the value for source is the same as bit 15:8 of DSP registers 0x08, | ||
814 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B | ||
815 | * | ||
816 | * this function replaces msp3400c_setstereo | ||
817 | */ | ||
818 | static void msp34xxg_set_source(struct i2c_client *client, int source) | ||
819 | { | ||
820 | struct msp_state *state = i2c_get_clientdata(client); | ||
821 | |||
822 | /* fix matrix mode to stereo and let the msp choose what | ||
823 | * to output according to 'source', as recommended | ||
824 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
825 | */ | ||
826 | int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); | ||
827 | |||
828 | v4l_dbg(1, client, "set source to %d (0x%x)\n", source, value); | ||
829 | /* Loudspeaker Output */ | ||
830 | msp_write_dsp(client, 0x08, value); | ||
831 | /* SCART1 DA Output */ | ||
832 | msp_write_dsp(client, 0x0a, value); | ||
833 | /* Quasi-peak detector */ | ||
834 | msp_write_dsp(client, 0x0c, value); | ||
835 | /* | ||
836 | * set identification threshold. Personally, I | ||
837 | * I set it to a higher value that the default | ||
838 | * of 0x190 to ignore noisy stereo signals. | ||
839 | * this needs tuning. (recommended range 0x00a0-0x03c0) | ||
840 | * 0x7f0 = forced mono mode | ||
841 | */ | ||
842 | /* a2 threshold for stereo/bilingual */ | ||
843 | msp_write_dem(client, 0x22, stereo_threshold); | ||
844 | state->source = source; | ||
845 | } | ||
846 | |||
847 | /* (re-)initialize the msp34xxg, according to the current norm in state->norm | ||
848 | * return 0 if it worked, -1 if it failed | ||
849 | */ | ||
850 | static int msp34xxg_reset(struct i2c_client *client) | ||
851 | { | ||
852 | struct msp_state *state = i2c_get_clientdata(client); | ||
853 | int modus, std; | ||
854 | |||
855 | if (msp_reset(client)) | ||
856 | return -1; | ||
857 | |||
858 | /* make sure that input/output is muted (paranoid mode) */ | ||
859 | /* ACB, mute DSP input, mute SCART 1 */ | ||
860 | if (msp_write_dsp(client, 0x13, 0x0f20)) | ||
861 | return -1; | ||
862 | |||
863 | if (state->has_i2s_conf) | ||
864 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
865 | |||
866 | /* step-by-step initialisation, as described in the manual */ | ||
867 | modus = msp_modus(client); | ||
868 | if (state->radio) | ||
869 | std = 0x40; | ||
870 | else | ||
871 | std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; | ||
872 | modus &= ~0x03; /* STATUS_CHANGE = 0 */ | ||
873 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */ | ||
874 | if (msp_write_dem(client, 0x30, modus)) | ||
875 | return -1; | ||
876 | if (msp_write_dem(client, 0x20, std)) | ||
877 | return -1; | ||
878 | |||
879 | /* write the dsps that may have an influence on | ||
880 | standard/audio autodetection right now */ | ||
881 | msp34xxg_set_source(client, state->source); | ||
882 | |||
883 | /* AM/FM Prescale [15:8] 75khz deviation */ | ||
884 | if (msp_write_dsp(client, 0x0e, 0x3000)) | ||
885 | return -1; | ||
886 | |||
887 | /* NICAM Prescale 9db gain (as recommended) */ | ||
888 | if (msp_write_dsp(client, 0x10, 0x5a00)) | ||
889 | return -1; | ||
890 | |||
891 | return 0; | ||
892 | } | ||
893 | |||
894 | int msp34xxg_thread(void *data) | ||
895 | { | ||
896 | struct i2c_client *client = data; | ||
897 | struct msp_state *state = i2c_get_clientdata(client); | ||
898 | int val, std, i; | ||
899 | |||
900 | v4l_dbg(1, client, "msp34xxg daemon started\n"); | ||
901 | |||
902 | state->source = 1; /* default */ | ||
903 | for (;;) { | ||
904 | v4l_dbg(2, client, "msp34xxg thread: sleep\n"); | ||
905 | msp_sleep(state, -1); | ||
906 | v4l_dbg(2, client, "msp34xxg thread: wakeup\n"); | ||
907 | |||
908 | restart: | ||
909 | v4l_dbg(1, client, "thread: restart scan\n"); | ||
910 | state->restart = 0; | ||
911 | if (kthread_should_stop()) | ||
912 | break; | ||
913 | |||
914 | /* setup the chip*/ | ||
915 | msp34xxg_reset(client); | ||
916 | std = standard; | ||
917 | if (std != 0x01) | ||
918 | goto unmute; | ||
919 | |||
920 | /* watch autodetect */ | ||
921 | v4l_dbg(1, client, "triggered autodetect, waiting for result\n"); | ||
922 | for (i = 0; i < 10; i++) { | ||
923 | if (msp_sleep(state, 100)) | ||
924 | goto restart; | ||
925 | |||
926 | /* check results */ | ||
927 | val = msp_read_dem(client, 0x7e); | ||
928 | if (val < 0x07ff) { | ||
929 | std = val; | ||
930 | break; | ||
931 | } | ||
932 | v4l_dbg(2, client, "detection still in progress\n"); | ||
933 | } | ||
934 | if (std == 1) { | ||
935 | v4l_dbg(1, client, "detection still in progress after 10 tries. giving up.\n"); | ||
936 | continue; | ||
937 | } | ||
938 | |||
939 | unmute: | ||
940 | state->std = std; | ||
941 | v4l_dbg(1, client, "current standard: %s (0x%04x)\n", | ||
942 | msp_standard_std_name(std), std); | ||
943 | |||
944 | /* unmute: dispatch sound to scart output, set scart volume */ | ||
945 | msp_set_audio(client); | ||
946 | |||
947 | /* restore ACB */ | ||
948 | if (msp_write_dsp(client, 0x13, state->acb)) | ||
949 | return -1; | ||
950 | |||
951 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
952 | } | ||
953 | v4l_dbg(1, client, "thread: exit\n"); | ||
954 | return 0; | ||
955 | } | ||
956 | |||
957 | void msp34xxg_detect_stereo(struct i2c_client *client) | ||
958 | { | ||
959 | struct msp_state *state = i2c_get_clientdata(client); | ||
960 | |||
961 | int status = msp_read_dem(client, 0x0200); | ||
962 | int is_bilingual = status & 0x100; | ||
963 | int is_stereo = status & 0x40; | ||
964 | |||
965 | state->rxsubchans = 0; | ||
966 | if (is_stereo) | ||
967 | state->rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
968 | else | ||
969 | state->rxsubchans |= V4L2_TUNER_SUB_MONO; | ||
970 | if (is_bilingual) { | ||
971 | state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
972 | /* I'm supposed to check whether it's SAP or not | ||
973 | * and set only LANG2/SAP in this case. Yet, the MSP | ||
974 | * does a lot of work to hide this and handle everything | ||
975 | * the same way. I don't want to work around it so unless | ||
976 | * this is a problem, I'll handle SAP just like lang1/lang2. | ||
977 | */ | ||
978 | } | ||
979 | v4l_dbg(1, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", | ||
980 | status, is_stereo, is_bilingual, state->rxsubchans); | ||
981 | } | ||
982 | |||
983 | void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | ||
984 | { | ||
985 | struct msp_state *state = i2c_get_clientdata(client); | ||
986 | int source; | ||
987 | |||
988 | switch (audmode) { | ||
989 | case V4L2_TUNER_MODE_MONO: | ||
990 | source = 0; /* mono only */ | ||
991 | break; | ||
992 | case V4L2_TUNER_MODE_STEREO: | ||
993 | source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ | ||
994 | /* problem: that could also mean 2 (scart input) */ | ||
995 | break; | ||
996 | case V4L2_TUNER_MODE_LANG1: | ||
997 | source = 3; /* stereo or A */ | ||
998 | break; | ||
999 | case V4L2_TUNER_MODE_LANG2: | ||
1000 | source = 4; /* stereo or B */ | ||
1001 | break; | ||
1002 | default: | ||
1003 | audmode = 0; | ||
1004 | source = 1; | ||
1005 | break; | ||
1006 | } | ||
1007 | state->audmode = audmode; | ||
1008 | msp34xxg_set_source(client, source); | ||
1009 | } | ||
1010 | |||
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c deleted file mode 100644 index 183253e2dd91..000000000000 --- a/drivers/media/video/msp3400.c +++ /dev/null | |||
@@ -1,2229 +0,0 @@ | |||
1 | /* | ||
2 | * programming the msp34* sound processor family | ||
3 | * | ||
4 | * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org> | ||
5 | * | ||
6 | * what works and what doesn't: | ||
7 | * | ||
8 | * AM-Mono | ||
9 | * Support for Hauppauge cards added (decoding handled by tuner) added by | ||
10 | * Frederic Crozat <fcrozat@mail.dotcom.fr> | ||
11 | * | ||
12 | * FM-Mono | ||
13 | * should work. The stereo modes are backward compatible to FM-mono, | ||
14 | * therefore FM-Mono should be allways available. | ||
15 | * | ||
16 | * FM-Stereo (B/G, used in germany) | ||
17 | * should work, with autodetect | ||
18 | * | ||
19 | * FM-Stereo (satellite) | ||
20 | * should work, no autodetect (i.e. default is mono, but you can | ||
21 | * switch to stereo -- untested) | ||
22 | * | ||
23 | * NICAM (B/G, L , used in UK, Scandinavia, Spain and France) | ||
24 | * should work, with autodetect. Support for NICAM was added by | ||
25 | * Pekka Pietikainen <pp@netppl.fi> | ||
26 | * | ||
27 | * | ||
28 | * TODO: | ||
29 | * - better SAT support | ||
30 | * | ||
31 | * | ||
32 | * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
33 | * using soundcore instead of OSS | ||
34 | * | ||
35 | */ | ||
36 | |||
37 | #include <linux/config.h> | ||
38 | #include <linux/module.h> | ||
39 | #include <linux/moduleparam.h> | ||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/string.h> | ||
43 | #include <linux/timer.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/errno.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/i2c.h> | ||
48 | #include <linux/videodev.h> | ||
49 | #include <linux/init.h> | ||
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/kthread.h> | ||
52 | #include <linux/suspend.h> | ||
53 | #include <asm/semaphore.h> | ||
54 | #include <asm/pgtable.h> | ||
55 | |||
56 | #include <media/audiochip.h> | ||
57 | #include "msp3400.h" | ||
58 | |||
59 | #define msp3400_dbg(fmt, arg...) \ | ||
60 | do { \ | ||
61 | if (debug) \ | ||
62 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
63 | client->driver->driver.name, \ | ||
64 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
65 | } while (0) | ||
66 | |||
67 | /* Medium volume debug. */ | ||
68 | #define msp3400_dbg_mediumvol(fmt, arg...) \ | ||
69 | do { \ | ||
70 | if (debug >= 2) \ | ||
71 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
72 | client->driver->driver.name, \ | ||
73 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
74 | } while (0) | ||
75 | |||
76 | /* High volume debug. Use with care. */ | ||
77 | #define msp3400_dbg_highvol(fmt, arg...) \ | ||
78 | do { \ | ||
79 | if (debug >= 16) \ | ||
80 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
81 | client->driver->driver.name, \ | ||
82 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
83 | } while (0) | ||
84 | |||
85 | #define msp3400_err(fmt, arg...) do { \ | ||
86 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
87 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
88 | #define msp3400_warn(fmt, arg...) do { \ | ||
89 | printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
90 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
91 | #define msp3400_info(fmt, arg...) do { \ | ||
92 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
93 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
94 | |||
95 | #define OPMODE_AUTO -1 | ||
96 | #define OPMODE_MANUAL 0 | ||
97 | #define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ | ||
98 | #define OPMODE_SIMPLER 2 /* use shorter programming (>= msp34xxG) */ | ||
99 | |||
100 | /* insmod parameters */ | ||
101 | static int opmode = OPMODE_AUTO; | ||
102 | static int debug = 0; /* debug output */ | ||
103 | static int once = 0; /* no continous stereo monitoring */ | ||
104 | static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), | ||
105 | the autoscan seems work well only with FM... */ | ||
106 | static int standard = 1; /* Override auto detect of audio standard, if needed. */ | ||
107 | static int dolby = 0; | ||
108 | |||
109 | static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual | ||
110 | (msp34xxg only) 0x00a0-0x03c0 */ | ||
111 | #define DFP_COUNT 0x41 | ||
112 | static const int bl_dfp[] = { | ||
113 | 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a, | ||
114 | 0x0b, 0x0d, 0x0e, 0x10 | ||
115 | }; | ||
116 | |||
117 | #define IS_MSP34XX_G(msp) ((msp)->opmode==2) | ||
118 | |||
119 | struct msp3400c { | ||
120 | int rev1,rev2; | ||
121 | |||
122 | int opmode; | ||
123 | int nicam; | ||
124 | int mode; | ||
125 | int norm; | ||
126 | int stereo; | ||
127 | int nicam_on; | ||
128 | int acb; | ||
129 | int in_scart; | ||
130 | int i2s_mode; | ||
131 | int main, second; /* sound carrier */ | ||
132 | int input; | ||
133 | int source; /* see msp34xxg_set_source */ | ||
134 | |||
135 | /* v4l2 */ | ||
136 | int audmode; | ||
137 | int rxsubchans; | ||
138 | |||
139 | int muted; | ||
140 | int left, right; /* volume */ | ||
141 | int bass, treble; | ||
142 | |||
143 | /* shadow register set */ | ||
144 | int dfp_regs[DFP_COUNT]; | ||
145 | |||
146 | /* thread */ | ||
147 | struct task_struct *kthread; | ||
148 | wait_queue_head_t wq; | ||
149 | int restart:1; | ||
150 | int watch_stereo:1; | ||
151 | }; | ||
152 | |||
153 | #define MIN(a,b) (((a)>(b))?(b):(a)) | ||
154 | #define MAX(a,b) (((a)>(b))?(a):(b)) | ||
155 | #define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) | ||
156 | #define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') | ||
157 | #define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') | ||
158 | #define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@') | ||
159 | |||
160 | #define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */ | ||
161 | |||
162 | /* ---------------------------------------------------------------------- */ | ||
163 | |||
164 | /* read-only */ | ||
165 | module_param(opmode, int, 0444); | ||
166 | |||
167 | /* read-write */ | ||
168 | module_param(once, int, 0644); | ||
169 | module_param(debug, int, 0644); | ||
170 | module_param(stereo_threshold, int, 0644); | ||
171 | module_param(standard, int, 0644); | ||
172 | module_param(amsound, int, 0644); | ||
173 | module_param(dolby, int, 0644); | ||
174 | |||
175 | MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Simple, 2=Simpler"); | ||
176 | MODULE_PARM_DESC(once, "No continuous stereo monitoring"); | ||
177 | MODULE_PARM_DESC(debug, "Enable debug messages"); | ||
178 | MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo"); | ||
179 | MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect"); | ||
180 | MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); | ||
181 | MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); | ||
182 | |||
183 | /* ---------------------------------------------------------------------- */ | ||
184 | |||
185 | #define I2C_MSP3400C 0x80 | ||
186 | #define I2C_MSP3400C_ALT 0x88 | ||
187 | |||
188 | #define I2C_MSP3400C_DEM 0x10 | ||
189 | #define I2C_MSP3400C_DFP 0x12 | ||
190 | |||
191 | /* Addresses to scan */ | ||
192 | static unsigned short normal_i2c[] = { | ||
193 | I2C_MSP3400C >> 1, | ||
194 | I2C_MSP3400C_ALT >> 1, | ||
195 | I2C_CLIENT_END | ||
196 | }; | ||
197 | I2C_CLIENT_INSMOD; | ||
198 | |||
199 | MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); | ||
200 | MODULE_AUTHOR("Gerd Knorr"); | ||
201 | MODULE_LICENSE("GPL"); | ||
202 | |||
203 | /* ----------------------------------------------------------------------- */ | ||
204 | /* functions for talking to the MSP3400C Sound processor */ | ||
205 | |||
206 | static int msp3400c_reset(struct i2c_client *client) | ||
207 | { | ||
208 | /* reset and read revision code */ | ||
209 | static char reset_off[3] = { 0x00, 0x80, 0x00 }; | ||
210 | static char reset_on[3] = { 0x00, 0x00, 0x00 }; | ||
211 | static char write[3] = { I2C_MSP3400C_DFP + 1, 0x00, 0x1e }; | ||
212 | char read[2]; | ||
213 | struct i2c_msg reset[2] = { | ||
214 | { client->addr, I2C_M_IGNORE_NAK, 3, reset_off }, | ||
215 | { client->addr, I2C_M_IGNORE_NAK, 3, reset_on }, | ||
216 | }; | ||
217 | struct i2c_msg test[2] = { | ||
218 | { client->addr, 0, 3, write }, | ||
219 | { client->addr, I2C_M_RD, 2, read }, | ||
220 | }; | ||
221 | |||
222 | msp3400_dbg_highvol("msp3400c_reset\n"); | ||
223 | if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || | ||
224 | (1 != i2c_transfer(client->adapter,&reset[1],1)) || | ||
225 | (2 != i2c_transfer(client->adapter,test,2)) ) { | ||
226 | msp3400_err("chip reset failed\n"); | ||
227 | return -1; | ||
228 | } | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int msp3400c_read(struct i2c_client *client, int dev, int addr) | ||
233 | { | ||
234 | int err,retval; | ||
235 | |||
236 | unsigned char write[3]; | ||
237 | unsigned char read[2]; | ||
238 | struct i2c_msg msgs[2] = { | ||
239 | { client->addr, 0, 3, write }, | ||
240 | { client->addr, I2C_M_RD, 2, read } | ||
241 | }; | ||
242 | |||
243 | write[0] = dev+1; | ||
244 | write[1] = addr >> 8; | ||
245 | write[2] = addr & 0xff; | ||
246 | |||
247 | for (err = 0; err < 3;) { | ||
248 | if (2 == i2c_transfer(client->adapter,msgs,2)) | ||
249 | break; | ||
250 | err++; | ||
251 | msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err, | ||
252 | dev, addr); | ||
253 | current->state = TASK_INTERRUPTIBLE; | ||
254 | schedule_timeout(msecs_to_jiffies(10)); | ||
255 | } | ||
256 | if (3 == err) { | ||
257 | msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | ||
258 | msp3400c_reset(client); | ||
259 | return -1; | ||
260 | } | ||
261 | retval = read[0] << 8 | read[1]; | ||
262 | msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); | ||
263 | return retval; | ||
264 | } | ||
265 | |||
266 | static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val) | ||
267 | { | ||
268 | int err; | ||
269 | unsigned char buffer[5]; | ||
270 | |||
271 | buffer[0] = dev; | ||
272 | buffer[1] = addr >> 8; | ||
273 | buffer[2] = addr & 0xff; | ||
274 | buffer[3] = val >> 8; | ||
275 | buffer[4] = val & 0xff; | ||
276 | |||
277 | msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); | ||
278 | for (err = 0; err < 3;) { | ||
279 | if (5 == i2c_master_send(client, buffer, 5)) | ||
280 | break; | ||
281 | err++; | ||
282 | msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err, | ||
283 | dev, addr); | ||
284 | current->state = TASK_INTERRUPTIBLE; | ||
285 | schedule_timeout(msecs_to_jiffies(10)); | ||
286 | } | ||
287 | if (3 == err) { | ||
288 | msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n"); | ||
289 | msp3400c_reset(client); | ||
290 | return -1; | ||
291 | } | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | /* ------------------------------------------------------------------------ */ | ||
296 | |||
297 | /* This macro is allowed for *constants* only, gcc must calculate it | ||
298 | at compile time. Remember -- no floats in kernel mode */ | ||
299 | #define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24))) | ||
300 | |||
301 | #define MSP_MODE_AM_DETECT 0 | ||
302 | #define MSP_MODE_FM_RADIO 2 | ||
303 | #define MSP_MODE_FM_TERRA 3 | ||
304 | #define MSP_MODE_FM_SAT 4 | ||
305 | #define MSP_MODE_FM_NICAM1 5 | ||
306 | #define MSP_MODE_FM_NICAM2 6 | ||
307 | #define MSP_MODE_AM_NICAM 7 | ||
308 | #define MSP_MODE_BTSC 8 | ||
309 | #define MSP_MODE_EXTERN 9 | ||
310 | |||
311 | static struct MSP_INIT_DATA_DEM { | ||
312 | int fir1[6]; | ||
313 | int fir2[6]; | ||
314 | int cdo1; | ||
315 | int cdo2; | ||
316 | int ad_cv; | ||
317 | int mode_reg; | ||
318 | int dfp_src; | ||
319 | int dfp_matrix; | ||
320 | } msp_init_data[] = { | ||
321 | { /* AM (for carrier detect / msp3400) */ | ||
322 | {75, 19, 36, 35, 39, 40}, | ||
323 | {75, 19, 36, 35, 39, 40}, | ||
324 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
325 | 0x00d0, 0x0500, 0x0020, 0x3000 | ||
326 | },{ /* AM (for carrier detect / msp3410) */ | ||
327 | {-1, -1, -8, 2, 59, 126}, | ||
328 | {-1, -1, -8, 2, 59, 126}, | ||
329 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
330 | 0x00d0, 0x0100, 0x0020, 0x3000 | ||
331 | },{ /* FM Radio */ | ||
332 | {-8, -8, 4, 6, 78, 107}, | ||
333 | {-8, -8, 4, 6, 78, 107}, | ||
334 | MSP_CARRIER(10.7), MSP_CARRIER(10.7), | ||
335 | 0x00d0, 0x0480, 0x0020, 0x3000 | ||
336 | },{ /* Terrestial FM-mono + FM-stereo */ | ||
337 | {3, 18, 27, 48, 66, 72}, | ||
338 | {3, 18, 27, 48, 66, 72}, | ||
339 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
340 | 0x00d0, 0x0480, 0x0030, 0x3000 | ||
341 | },{ /* Sat FM-mono */ | ||
342 | { 1, 9, 14, 24, 33, 37}, | ||
343 | { 3, 18, 27, 48, 66, 72}, | ||
344 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | ||
345 | 0x00c6, 0x0480, 0x0000, 0x3000 | ||
346 | },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ | ||
347 | {-2, -8, -10, 10, 50, 86}, | ||
348 | {3, 18, 27, 48, 66, 72}, | ||
349 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | ||
350 | 0x00d0, 0x0040, 0x0120, 0x3000 | ||
351 | },{ /* NICAM/FM -- I (6.0/6.552) */ | ||
352 | {2, 4, -6, -4, 40, 94}, | ||
353 | {3, 18, 27, 48, 66, 72}, | ||
354 | MSP_CARRIER(6.0), MSP_CARRIER(6.0), | ||
355 | 0x00d0, 0x0040, 0x0120, 0x3000 | ||
356 | },{ /* NICAM/AM -- L (6.5/5.85) */ | ||
357 | {-2, -8, -10, 10, 50, 86}, | ||
358 | {-4, -12, -9, 23, 79, 126}, | ||
359 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | ||
360 | 0x00c6, 0x0140, 0x0120, 0x7c03 | ||
361 | }, | ||
362 | }; | ||
363 | |||
364 | struct CARRIER_DETECT { | ||
365 | int cdo; | ||
366 | char *name; | ||
367 | }; | ||
368 | |||
369 | static struct CARRIER_DETECT carrier_detect_main[] = { | ||
370 | /* main carrier */ | ||
371 | { MSP_CARRIER(4.5), "4.5 NTSC" }, | ||
372 | { MSP_CARRIER(5.5), "5.5 PAL B/G" }, | ||
373 | { MSP_CARRIER(6.0), "6.0 PAL I" }, | ||
374 | { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } | ||
375 | }; | ||
376 | |||
377 | static struct CARRIER_DETECT carrier_detect_55[] = { | ||
378 | /* PAL B/G */ | ||
379 | { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, | ||
380 | { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } | ||
381 | }; | ||
382 | |||
383 | static struct CARRIER_DETECT carrier_detect_65[] = { | ||
384 | /* PAL SAT / SECAM */ | ||
385 | { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, | ||
386 | { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, | ||
387 | { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" }, | ||
388 | { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" }, | ||
389 | { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" }, | ||
390 | { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, | ||
391 | }; | ||
392 | |||
393 | #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) | ||
394 | |||
395 | /* ----------------------------------------------------------------------- * | ||
396 | * bits 9 8 5 - SCART DSP input Select: | ||
397 | * 0 0 0 - SCART 1 to DSP input (reset position) | ||
398 | * 0 1 0 - MONO to DSP input | ||
399 | * 1 0 0 - SCART 2 to DSP input | ||
400 | * 1 1 1 - Mute DSP input | ||
401 | * | ||
402 | * bits 11 10 6 - SCART 1 Output Select: | ||
403 | * 0 0 0 - undefined (reset position) | ||
404 | * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) | ||
405 | * 1 0 0 - MONO input to SCART 1 Output | ||
406 | * 1 1 0 - SCART 1 DA to SCART 1 Output | ||
407 | * 0 0 1 - SCART 2 DA to SCART 1 Output | ||
408 | * 0 1 1 - SCART 1 Input to SCART 1 Output | ||
409 | * 1 1 1 - Mute SCART 1 Output | ||
410 | * | ||
411 | * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): | ||
412 | * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) | ||
413 | * 0 1 0 - SCART 1 Input to SCART 2 Output | ||
414 | * 1 0 0 - MONO input to SCART 2 Output | ||
415 | * 0 0 1 - SCART 2 DA to SCART 2 Output | ||
416 | * 0 1 1 - SCART 2 Input to SCART 2 Output | ||
417 | * 1 1 0 - Mute SCART 2 Output | ||
418 | * | ||
419 | * Bits 4 to 0 should be zero. | ||
420 | * ----------------------------------------------------------------------- */ | ||
421 | |||
422 | static int scarts[3][9] = { | ||
423 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ | ||
424 | /* SCART DSP Input select */ | ||
425 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, | ||
426 | /* SCART1 Output select */ | ||
427 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | ||
428 | /* SCART2 Output select */ | ||
429 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | ||
430 | }; | ||
431 | |||
432 | static char *scart_names[] = { | ||
433 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" | ||
434 | }; | ||
435 | |||
436 | static void msp3400c_set_scart(struct i2c_client *client, int in, int out) | ||
437 | { | ||
438 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
439 | |||
440 | msp->in_scart=in; | ||
441 | |||
442 | if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { | ||
443 | if (-1 == scarts[out][in]) | ||
444 | return; | ||
445 | |||
446 | msp->acb &= ~scarts[out][SCART_MASK]; | ||
447 | msp->acb |= scarts[out][in]; | ||
448 | } else | ||
449 | msp->acb = 0xf60; /* Mute Input and SCART 1 Output */ | ||
450 | |||
451 | msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n", | ||
452 | scart_names[in], out, msp->acb); | ||
453 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb); | ||
454 | |||
455 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | ||
456 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
457 | } | ||
458 | |||
459 | /* ------------------------------------------------------------------------ */ | ||
460 | |||
461 | static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | ||
462 | { | ||
463 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff); | ||
464 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12); | ||
465 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff); | ||
466 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12); | ||
467 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ | ||
468 | } | ||
469 | |||
470 | static void msp3400c_setvolume(struct i2c_client *client, | ||
471 | int muted, int left, int right) | ||
472 | { | ||
473 | int vol = 0, val = 0, balance = 0; | ||
474 | |||
475 | if (!muted) { | ||
476 | /* 0x7f instead if 0x73 here has sound quality issues, | ||
477 | * probably due to overmodulation + clipping ... */ | ||
478 | vol = (left > right) ? left : right; | ||
479 | val = (vol * 0x73 / 65535) << 8; | ||
480 | } | ||
481 | if (vol > 0) { | ||
482 | balance = ((right - left) * 127) / vol; | ||
483 | } | ||
484 | |||
485 | msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", | ||
486 | muted ? "on" : "off", left, right, val >> 8, balance); | ||
487 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ | ||
488 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ | ||
489 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, | ||
490 | muted ? 0x1 : (val | 0x1)); | ||
491 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8); | ||
492 | } | ||
493 | |||
494 | static void msp3400c_setbass(struct i2c_client *client, int bass) | ||
495 | { | ||
496 | int val = ((bass-32768) * 0x60 / 65535) << 8; | ||
497 | |||
498 | msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8); | ||
499 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ | ||
500 | } | ||
501 | |||
502 | static void msp3400c_settreble(struct i2c_client *client, int treble) | ||
503 | { | ||
504 | int val = ((treble-32768) * 0x60 / 65535) << 8; | ||
505 | |||
506 | msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8); | ||
507 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ | ||
508 | } | ||
509 | |||
510 | static void msp3400c_setmode(struct i2c_client *client, int type) | ||
511 | { | ||
512 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
513 | int i; | ||
514 | |||
515 | msp3400_dbg("setmode: %d\n",type); | ||
516 | msp->mode = type; | ||
517 | msp->audmode = V4L2_TUNER_MODE_MONO; | ||
518 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
519 | |||
520 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */ | ||
521 | msp_init_data[type].ad_cv); | ||
522 | |||
523 | for (i = 5; i >= 0; i--) /* fir 1 */ | ||
524 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001, | ||
525 | msp_init_data[type].fir1[i]); | ||
526 | |||
527 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */ | ||
528 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040); | ||
529 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000); | ||
530 | for (i = 5; i >= 0; i--) | ||
531 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, | ||
532 | msp_init_data[type].fir2[i]); | ||
533 | |||
534 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */ | ||
535 | msp_init_data[type].mode_reg); | ||
536 | |||
537 | msp3400c_setcarrier(client, msp_init_data[type].cdo1, | ||
538 | msp_init_data[type].cdo2); | ||
539 | |||
540 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ | ||
541 | |||
542 | if (dolby) { | ||
543 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, | ||
544 | 0x0520); /* I2S1 */ | ||
545 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, | ||
546 | 0x0620); /* I2S2 */ | ||
547 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, | ||
548 | msp_init_data[type].dfp_src); | ||
549 | } else { | ||
550 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, | ||
551 | msp_init_data[type].dfp_src); | ||
552 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, | ||
553 | msp_init_data[type].dfp_src); | ||
554 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, | ||
555 | msp_init_data[type].dfp_src); | ||
556 | } | ||
557 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a, | ||
558 | msp_init_data[type].dfp_src); | ||
559 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, | ||
560 | msp_init_data[type].dfp_matrix); | ||
561 | |||
562 | if (HAVE_NICAM(msp)) { | ||
563 | /* nicam prescale */ | ||
564 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */ | ||
565 | } | ||
566 | } | ||
567 | |||
568 | /* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */ | ||
569 | static int best_video_sound(int rxsubchans) | ||
570 | { | ||
571 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
572 | return V4L2_TUNER_MODE_STEREO; | ||
573 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | ||
574 | return V4L2_TUNER_MODE_LANG1; | ||
575 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) | ||
576 | return V4L2_TUNER_MODE_LANG2; | ||
577 | return V4L2_TUNER_MODE_MONO; | ||
578 | } | ||
579 | |||
580 | /* turn on/off nicam + stereo */ | ||
581 | static void msp3400c_setstereo(struct i2c_client *client, int mode) | ||
582 | { | ||
583 | static char *strmode[] = { "0", "mono", "stereo", "3", | ||
584 | "lang1", "5", "6", "7", "lang2" | ||
585 | }; | ||
586 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
587 | int nicam = 0; /* channel source: FM/AM or nicam */ | ||
588 | int src = 0; | ||
589 | |||
590 | if (IS_MSP34XX_G(msp)) { | ||
591 | /* this method would break everything, let's make sure | ||
592 | * it's never called | ||
593 | */ | ||
594 | msp3400_dbg | ||
595 | ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n", | ||
596 | mode); | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | /* switch demodulator */ | ||
601 | switch (msp->mode) { | ||
602 | case MSP_MODE_FM_TERRA: | ||
603 | msp3400_dbg("FM setstereo: %s\n", strmode[mode]); | ||
604 | msp3400c_setcarrier(client,msp->second,msp->main); | ||
605 | switch (mode) { | ||
606 | case V4L2_TUNER_MODE_STEREO: | ||
607 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); | ||
608 | break; | ||
609 | case V4L2_TUNER_MODE_MONO: | ||
610 | case V4L2_TUNER_MODE_LANG1: | ||
611 | case V4L2_TUNER_MODE_LANG2: | ||
612 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000); | ||
613 | break; | ||
614 | } | ||
615 | break; | ||
616 | case MSP_MODE_FM_SAT: | ||
617 | msp3400_dbg("SAT setstereo: %s\n", strmode[mode]); | ||
618 | switch (mode) { | ||
619 | case V4L2_TUNER_MODE_MONO: | ||
620 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); | ||
621 | break; | ||
622 | case V4L2_TUNER_MODE_STEREO: | ||
623 | msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); | ||
624 | break; | ||
625 | case V4L2_TUNER_MODE_LANG1: | ||
626 | msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); | ||
627 | break; | ||
628 | case V4L2_TUNER_MODE_LANG2: | ||
629 | msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); | ||
630 | break; | ||
631 | } | ||
632 | break; | ||
633 | case MSP_MODE_FM_NICAM1: | ||
634 | case MSP_MODE_FM_NICAM2: | ||
635 | case MSP_MODE_AM_NICAM: | ||
636 | msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]); | ||
637 | msp3400c_setcarrier(client,msp->second,msp->main); | ||
638 | if (msp->nicam_on) | ||
639 | nicam=0x0100; | ||
640 | break; | ||
641 | case MSP_MODE_BTSC: | ||
642 | msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]); | ||
643 | nicam=0x0300; | ||
644 | break; | ||
645 | case MSP_MODE_EXTERN: | ||
646 | msp3400_dbg("extern setstereo: %s\n",strmode[mode]); | ||
647 | nicam = 0x0200; | ||
648 | break; | ||
649 | case MSP_MODE_FM_RADIO: | ||
650 | msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]); | ||
651 | break; | ||
652 | default: | ||
653 | msp3400_dbg("mono setstereo\n"); | ||
654 | return; | ||
655 | } | ||
656 | |||
657 | /* switch audio */ | ||
658 | switch (best_video_sound(mode)) { | ||
659 | case V4L2_TUNER_MODE_STEREO: | ||
660 | src = 0x0020 | nicam; | ||
661 | break; | ||
662 | case V4L2_TUNER_MODE_MONO: | ||
663 | if (msp->mode == MSP_MODE_AM_NICAM) { | ||
664 | msp3400_dbg("switching to AM mono\n"); | ||
665 | /* AM mono decoding is handled by tuner, not MSP chip */ | ||
666 | /* SCART switching control register */ | ||
667 | msp3400c_set_scart(client,SCART_MONO,0); | ||
668 | src = 0x0200; | ||
669 | break; | ||
670 | } | ||
671 | case V4L2_TUNER_MODE_LANG1: | ||
672 | src = 0x0000 | nicam; | ||
673 | break; | ||
674 | case V4L2_TUNER_MODE_LANG2: | ||
675 | src = 0x0010 | nicam; | ||
676 | break; | ||
677 | } | ||
678 | msp3400_dbg("setstereo final source/matrix = 0x%x\n", src); | ||
679 | |||
680 | if (dolby) { | ||
681 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); | ||
682 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620); | ||
683 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); | ||
684 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); | ||
685 | } else { | ||
686 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src); | ||
687 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src); | ||
688 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); | ||
689 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); | ||
690 | } | ||
691 | } | ||
692 | |||
693 | static void | ||
694 | msp3400c_print_mode(struct i2c_client *client) | ||
695 | { | ||
696 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
697 | |||
698 | if (msp->main == msp->second) { | ||
699 | msp3400_dbg("mono sound carrier: %d.%03d MHz\n", | ||
700 | msp->main/910000,(msp->main/910)%1000); | ||
701 | } else { | ||
702 | msp3400_dbg("main sound carrier: %d.%03d MHz\n", | ||
703 | msp->main/910000,(msp->main/910)%1000); | ||
704 | } | ||
705 | if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2) | ||
706 | msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n", | ||
707 | msp->second/910000,(msp->second/910)%1000); | ||
708 | if (msp->mode == MSP_MODE_AM_NICAM) | ||
709 | msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n", | ||
710 | msp->second/910000,(msp->second/910)%1000); | ||
711 | if (msp->mode == MSP_MODE_FM_TERRA && | ||
712 | msp->main != msp->second) { | ||
713 | msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n", | ||
714 | msp->second/910000,(msp->second/910)%1000); | ||
715 | } | ||
716 | } | ||
717 | |||
718 | #define MSP3400_MAX 4 | ||
719 | static struct i2c_client *msps[MSP3400_MAX]; | ||
720 | static void msp3400c_restore_dfp(struct i2c_client *client) | ||
721 | { | ||
722 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
723 | int i; | ||
724 | |||
725 | for (i = 0; i < DFP_COUNT; i++) { | ||
726 | if (-1 == msp->dfp_regs[i]) | ||
727 | continue; | ||
728 | msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); | ||
729 | } | ||
730 | } | ||
731 | |||
732 | /* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ | ||
733 | static int msp3400c_write_dfp_with_default(struct i2c_client *client, | ||
734 | int addr, int default_value) | ||
735 | { | ||
736 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
737 | int value = default_value; | ||
738 | if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr]) | ||
739 | value = msp->dfp_regs[addr]; | ||
740 | return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value); | ||
741 | } | ||
742 | |||
743 | /* ----------------------------------------------------------------------- */ | ||
744 | |||
745 | struct REGISTER_DUMP { | ||
746 | int addr; | ||
747 | char *name; | ||
748 | }; | ||
749 | |||
750 | struct REGISTER_DUMP d1[] = { | ||
751 | {0x007e, "autodetect"}, | ||
752 | {0x0023, "C_AD_BITS "}, | ||
753 | {0x0038, "ADD_BITS "}, | ||
754 | {0x003e, "CIB_BITS "}, | ||
755 | {0x0057, "ERROR_RATE"}, | ||
756 | }; | ||
757 | |||
758 | static int autodetect_stereo(struct i2c_client *client) | ||
759 | { | ||
760 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
761 | int val; | ||
762 | int rxsubchans = msp->rxsubchans; | ||
763 | int newnicam = msp->nicam_on; | ||
764 | int update = 0; | ||
765 | |||
766 | switch (msp->mode) { | ||
767 | case MSP_MODE_FM_TERRA: | ||
768 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); | ||
769 | if (val > 32767) | ||
770 | val -= 65536; | ||
771 | msp3400_dbg("stereo detect register: %d\n",val); | ||
772 | if (val > 4096) { | ||
773 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | ||
774 | } else if (val < -4096) { | ||
775 | rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
776 | } else { | ||
777 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
778 | } | ||
779 | newnicam = 0; | ||
780 | break; | ||
781 | case MSP_MODE_FM_NICAM1: | ||
782 | case MSP_MODE_FM_NICAM2: | ||
783 | case MSP_MODE_AM_NICAM: | ||
784 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); | ||
785 | msp3400_dbg("nicam sync=%d, mode=%d\n", | ||
786 | val & 1, (val & 0x1e) >> 1); | ||
787 | |||
788 | if (val & 1) { | ||
789 | /* nicam synced */ | ||
790 | switch ((val & 0x1e) >> 1) { | ||
791 | case 0: | ||
792 | case 8: | ||
793 | rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
794 | break; | ||
795 | case 1: | ||
796 | case 9: | ||
797 | rxsubchans = V4L2_TUNER_SUB_MONO | ||
798 | | V4L2_TUNER_SUB_LANG1; | ||
799 | break; | ||
800 | case 2: | ||
801 | case 10: | ||
802 | rxsubchans = V4L2_TUNER_SUB_MONO | ||
803 | | V4L2_TUNER_SUB_LANG1 | ||
804 | | V4L2_TUNER_SUB_LANG2; | ||
805 | break; | ||
806 | default: | ||
807 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
808 | break; | ||
809 | } | ||
810 | newnicam=1; | ||
811 | } else { | ||
812 | newnicam = 0; | ||
813 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
814 | } | ||
815 | break; | ||
816 | case MSP_MODE_BTSC: | ||
817 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); | ||
818 | msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n", | ||
819 | val, | ||
820 | (val & 0x0002) ? "no" : "yes", | ||
821 | (val & 0x0004) ? "no" : "yes", | ||
822 | (val & 0x0040) ? "stereo" : "mono", | ||
823 | (val & 0x0080) ? ", nicam 2nd mono" : "", | ||
824 | (val & 0x0100) ? ", bilingual/SAP" : ""); | ||
825 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
826 | if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
827 | if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; | ||
828 | break; | ||
829 | } | ||
830 | if (rxsubchans != msp->rxsubchans) { | ||
831 | update = 1; | ||
832 | msp3400_dbg("watch: rxsubchans %d => %d\n", | ||
833 | msp->rxsubchans,rxsubchans); | ||
834 | msp->rxsubchans = rxsubchans; | ||
835 | } | ||
836 | if (newnicam != msp->nicam_on) { | ||
837 | update = 1; | ||
838 | msp3400_dbg("watch: nicam %d => %d\n", | ||
839 | msp->nicam_on,newnicam); | ||
840 | msp->nicam_on = newnicam; | ||
841 | } | ||
842 | return update; | ||
843 | } | ||
844 | |||
845 | /* | ||
846 | * A kernel thread for msp3400 control -- we don't want to block the | ||
847 | * in the ioctl while doing the sound carrier & stereo detect | ||
848 | */ | ||
849 | |||
850 | static int msp34xx_sleep(struct msp3400c *msp, int timeout) | ||
851 | { | ||
852 | DECLARE_WAITQUEUE(wait, current); | ||
853 | |||
854 | add_wait_queue(&msp->wq, &wait); | ||
855 | if (!kthread_should_stop()) { | ||
856 | if (timeout < 0) { | ||
857 | set_current_state(TASK_INTERRUPTIBLE); | ||
858 | schedule(); | ||
859 | } else { | ||
860 | schedule_timeout_interruptible | ||
861 | (msecs_to_jiffies(timeout)); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | remove_wait_queue(&msp->wq, &wait); | ||
866 | try_to_freeze(); | ||
867 | return msp->restart; | ||
868 | } | ||
869 | |||
870 | /* stereo/multilang monitoring */ | ||
871 | static void watch_stereo(struct i2c_client *client) | ||
872 | { | ||
873 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
874 | |||
875 | if (autodetect_stereo(client)) { | ||
876 | if (msp->stereo & V4L2_TUNER_MODE_STEREO) | ||
877 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); | ||
878 | else if (msp->stereo & VIDEO_SOUND_LANG1) | ||
879 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); | ||
880 | else | ||
881 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
882 | } | ||
883 | |||
884 | if (once) | ||
885 | msp->watch_stereo = 0; | ||
886 | } | ||
887 | |||
888 | |||
889 | static int msp3400c_thread(void *data) | ||
890 | { | ||
891 | struct i2c_client *client = data; | ||
892 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
893 | struct CARRIER_DETECT *cd; | ||
894 | int count, max1,max2,val1,val2, val,this; | ||
895 | |||
896 | |||
897 | msp3400_info("msp3400 daemon started\n"); | ||
898 | for (;;) { | ||
899 | msp3400_dbg_mediumvol("msp3400 thread: sleep\n"); | ||
900 | msp34xx_sleep(msp,-1); | ||
901 | msp3400_dbg_mediumvol("msp3400 thread: wakeup\n"); | ||
902 | |||
903 | restart: | ||
904 | msp3400_dbg("thread: restart scan\n"); | ||
905 | msp->restart = 0; | ||
906 | if (kthread_should_stop()) | ||
907 | break; | ||
908 | |||
909 | if (VIDEO_MODE_RADIO == msp->norm || | ||
910 | MSP_MODE_EXTERN == msp->mode) { | ||
911 | /* no carrier scan, just unmute */ | ||
912 | msp3400_info("thread: no carrier scan\n"); | ||
913 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
914 | continue; | ||
915 | } | ||
916 | |||
917 | /* mute */ | ||
918 | msp3400c_setvolume(client, msp->muted, 0, 0); | ||
919 | msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); | ||
920 | val1 = val2 = 0; | ||
921 | max1 = max2 = -1; | ||
922 | msp->watch_stereo = 0; | ||
923 | |||
924 | /* some time for the tuner to sync */ | ||
925 | if (msp34xx_sleep(msp,200)) | ||
926 | goto restart; | ||
927 | |||
928 | /* carrier detect pass #1 -- main carrier */ | ||
929 | cd = carrier_detect_main; | ||
930 | count = CARRIER_COUNT(carrier_detect_main); | ||
931 | |||
932 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | ||
933 | /* autodetect doesn't work well with AM ... */ | ||
934 | max1 = 3; | ||
935 | count = 0; | ||
936 | msp3400_dbg("AM sound override\n"); | ||
937 | } | ||
938 | |||
939 | for (this = 0; this < count; this++) { | ||
940 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | ||
941 | if (msp34xx_sleep(msp,100)) | ||
942 | goto restart; | ||
943 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b); | ||
944 | if (val > 32767) | ||
945 | val -= 65536; | ||
946 | if (val1 < val) | ||
947 | val1 = val, max1 = this; | ||
948 | msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name); | ||
949 | } | ||
950 | |||
951 | /* carrier detect pass #2 -- second (stereo) carrier */ | ||
952 | switch (max1) { | ||
953 | case 1: /* 5.5 */ | ||
954 | cd = carrier_detect_55; | ||
955 | count = CARRIER_COUNT(carrier_detect_55); | ||
956 | break; | ||
957 | case 3: /* 6.5 */ | ||
958 | cd = carrier_detect_65; | ||
959 | count = CARRIER_COUNT(carrier_detect_65); | ||
960 | break; | ||
961 | case 0: /* 4.5 */ | ||
962 | case 2: /* 6.0 */ | ||
963 | default: | ||
964 | cd = NULL; | ||
965 | count = 0; | ||
966 | break; | ||
967 | } | ||
968 | |||
969 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | ||
970 | /* autodetect doesn't work well with AM ... */ | ||
971 | cd = NULL; | ||
972 | count = 0; | ||
973 | max2 = 0; | ||
974 | } | ||
975 | for (this = 0; this < count; this++) { | ||
976 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | ||
977 | if (msp34xx_sleep(msp,100)) | ||
978 | goto restart; | ||
979 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b); | ||
980 | if (val > 32767) | ||
981 | val -= 65536; | ||
982 | if (val2 < val) | ||
983 | val2 = val, max2 = this; | ||
984 | msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name); | ||
985 | } | ||
986 | |||
987 | /* programm the msp3400 according to the results */ | ||
988 | msp->main = carrier_detect_main[max1].cdo; | ||
989 | switch (max1) { | ||
990 | case 1: /* 5.5 */ | ||
991 | if (max2 == 0) { | ||
992 | /* B/G FM-stereo */ | ||
993 | msp->second = carrier_detect_55[max2].cdo; | ||
994 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | ||
995 | msp->nicam_on = 0; | ||
996 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
997 | msp->watch_stereo = 1; | ||
998 | } else if (max2 == 1 && HAVE_NICAM(msp)) { | ||
999 | /* B/G NICAM */ | ||
1000 | msp->second = carrier_detect_55[max2].cdo; | ||
1001 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | ||
1002 | msp->nicam_on = 1; | ||
1003 | msp3400c_setcarrier(client, msp->second, msp->main); | ||
1004 | msp->watch_stereo = 1; | ||
1005 | } else { | ||
1006 | goto no_second; | ||
1007 | } | ||
1008 | break; | ||
1009 | case 2: /* 6.0 */ | ||
1010 | /* PAL I NICAM */ | ||
1011 | msp->second = MSP_CARRIER(6.552); | ||
1012 | msp3400c_setmode(client, MSP_MODE_FM_NICAM2); | ||
1013 | msp->nicam_on = 1; | ||
1014 | msp3400c_setcarrier(client, msp->second, msp->main); | ||
1015 | msp->watch_stereo = 1; | ||
1016 | break; | ||
1017 | case 3: /* 6.5 */ | ||
1018 | if (max2 == 1 || max2 == 2) { | ||
1019 | /* D/K FM-stereo */ | ||
1020 | msp->second = carrier_detect_65[max2].cdo; | ||
1021 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | ||
1022 | msp->nicam_on = 0; | ||
1023 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
1024 | msp->watch_stereo = 1; | ||
1025 | } else if (max2 == 0 && | ||
1026 | msp->norm == VIDEO_MODE_SECAM) { | ||
1027 | /* L NICAM or AM-mono */ | ||
1028 | msp->second = carrier_detect_65[max2].cdo; | ||
1029 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); | ||
1030 | msp->nicam_on = 0; | ||
1031 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
1032 | msp3400c_setcarrier(client, msp->second, msp->main); | ||
1033 | /* volume prescale for SCART (AM mono input) */ | ||
1034 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); | ||
1035 | msp->watch_stereo = 1; | ||
1036 | } else if (max2 == 0 && HAVE_NICAM(msp)) { | ||
1037 | /* D/K NICAM */ | ||
1038 | msp->second = carrier_detect_65[max2].cdo; | ||
1039 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | ||
1040 | msp->nicam_on = 1; | ||
1041 | msp3400c_setcarrier(client, msp->second, msp->main); | ||
1042 | msp->watch_stereo = 1; | ||
1043 | } else { | ||
1044 | goto no_second; | ||
1045 | } | ||
1046 | break; | ||
1047 | case 0: /* 4.5 */ | ||
1048 | default: | ||
1049 | no_second: | ||
1050 | msp->second = carrier_detect_main[max1].cdo; | ||
1051 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | ||
1052 | msp->nicam_on = 0; | ||
1053 | msp3400c_setcarrier(client, msp->second, msp->main); | ||
1054 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1055 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
1056 | break; | ||
1057 | } | ||
1058 | |||
1059 | /* unmute */ | ||
1060 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1061 | msp3400c_restore_dfp(client); | ||
1062 | |||
1063 | if (debug) | ||
1064 | msp3400c_print_mode(client); | ||
1065 | |||
1066 | /* monitor tv audio mode */ | ||
1067 | while (msp->watch_stereo) { | ||
1068 | if (msp34xx_sleep(msp,5000)) | ||
1069 | goto restart; | ||
1070 | watch_stereo(client); | ||
1071 | } | ||
1072 | } | ||
1073 | msp3400_dbg("thread: exit\n"); | ||
1074 | return 0; | ||
1075 | } | ||
1076 | |||
1077 | /* ----------------------------------------------------------------------- */ | ||
1078 | /* this one uses the automatic sound standard detection of newer */ | ||
1079 | /* msp34xx chip versions */ | ||
1080 | |||
1081 | static struct MODES { | ||
1082 | int retval; | ||
1083 | int main, second; | ||
1084 | char *name; | ||
1085 | } modelist[] = { | ||
1086 | { 0x0000, 0, 0, "ERROR" }, | ||
1087 | { 0x0001, 0, 0, "autodetect start" }, | ||
1088 | { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" }, | ||
1089 | { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" }, | ||
1090 | { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, | ||
1091 | { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, | ||
1092 | { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, | ||
1093 | { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, | ||
1094 | { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, | ||
1095 | { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, | ||
1096 | { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, | ||
1097 | { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, | ||
1098 | { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, | ||
1099 | { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, | ||
1100 | { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, | ||
1101 | { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" }, | ||
1102 | { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" }, | ||
1103 | { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" }, | ||
1104 | { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" }, | ||
1105 | { -1, 0, 0, NULL }, /* EOF */ | ||
1106 | }; | ||
1107 | |||
1108 | static inline const char *msp34xx_standard_mode_name(int mode) | ||
1109 | { | ||
1110 | int i; | ||
1111 | for (i = 0; modelist[i].name != NULL; i++) | ||
1112 | if (modelist[i].retval == mode) | ||
1113 | return modelist[i].name; | ||
1114 | return "unknown"; | ||
1115 | } | ||
1116 | |||
1117 | static int msp34xx_modus(struct i2c_client *client, int norm) | ||
1118 | { | ||
1119 | switch (norm) { | ||
1120 | case VIDEO_MODE_PAL: | ||
1121 | msp3400_dbg("video mode selected to PAL\n"); | ||
1122 | |||
1123 | #if 1 | ||
1124 | /* experimental: not sure this works with all chip versions */ | ||
1125 | return 0x7003; | ||
1126 | #else | ||
1127 | /* previous value, try this if it breaks ... */ | ||
1128 | return 0x1003; | ||
1129 | #endif | ||
1130 | case VIDEO_MODE_NTSC: /* BTSC */ | ||
1131 | msp3400_dbg("video mode selected to NTSC\n"); | ||
1132 | return 0x2003; | ||
1133 | case VIDEO_MODE_SECAM: | ||
1134 | msp3400_dbg("video mode selected to SECAM\n"); | ||
1135 | return 0x0003; | ||
1136 | case VIDEO_MODE_RADIO: | ||
1137 | msp3400_dbg("video mode selected to Radio\n"); | ||
1138 | return 0x0003; | ||
1139 | case VIDEO_MODE_AUTO: | ||
1140 | msp3400_dbg("video mode selected to Auto\n"); | ||
1141 | return 0x2003; | ||
1142 | default: | ||
1143 | return 0x0003; | ||
1144 | } | ||
1145 | } | ||
1146 | |||
1147 | static int msp34xx_standard(int norm) | ||
1148 | { | ||
1149 | switch (norm) { | ||
1150 | case VIDEO_MODE_PAL: | ||
1151 | return 1; | ||
1152 | case VIDEO_MODE_NTSC: /* BTSC */ | ||
1153 | return 0x0020; | ||
1154 | case VIDEO_MODE_SECAM: | ||
1155 | return 1; | ||
1156 | case VIDEO_MODE_RADIO: | ||
1157 | return 0x0040; | ||
1158 | default: | ||
1159 | return 1; | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | static int msp3410d_thread(void *data) | ||
1164 | { | ||
1165 | struct i2c_client *client = data; | ||
1166 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1167 | int mode,val,i,std; | ||
1168 | |||
1169 | msp3400_info("msp3410 daemon started\n"); | ||
1170 | |||
1171 | for (;;) { | ||
1172 | msp3400_dbg_mediumvol("msp3410 thread: sleep\n"); | ||
1173 | msp34xx_sleep(msp,-1); | ||
1174 | msp3400_dbg_mediumvol("msp3410 thread: wakeup\n"); | ||
1175 | |||
1176 | restart: | ||
1177 | msp3400_dbg("thread: restart scan\n"); | ||
1178 | msp->restart = 0; | ||
1179 | if (kthread_should_stop()) | ||
1180 | break; | ||
1181 | |||
1182 | if (msp->mode == MSP_MODE_EXTERN) { | ||
1183 | /* no carrier scan needed, just unmute */ | ||
1184 | msp3400_dbg("thread: no carrier scan\n"); | ||
1185 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1186 | continue; | ||
1187 | } | ||
1188 | |||
1189 | /* put into sane state (and mute) */ | ||
1190 | msp3400c_reset(client); | ||
1191 | |||
1192 | /* some time for the tuner to sync */ | ||
1193 | if (msp34xx_sleep(msp,200)) | ||
1194 | goto restart; | ||
1195 | |||
1196 | /* start autodetect */ | ||
1197 | mode = msp34xx_modus(client, msp->norm); | ||
1198 | std = msp34xx_standard(msp->norm); | ||
1199 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); | ||
1200 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); | ||
1201 | msp->watch_stereo = 0; | ||
1202 | |||
1203 | if (debug) | ||
1204 | msp3400_dbg("setting mode: %s (0x%04x)\n", | ||
1205 | msp34xx_standard_mode_name(std) ,std); | ||
1206 | |||
1207 | if (std != 1) { | ||
1208 | /* programmed some specific mode */ | ||
1209 | val = std; | ||
1210 | } else { | ||
1211 | /* triggered autodetect */ | ||
1212 | for (;;) { | ||
1213 | if (msp34xx_sleep(msp,100)) | ||
1214 | goto restart; | ||
1215 | |||
1216 | /* check results */ | ||
1217 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); | ||
1218 | if (val < 0x07ff) | ||
1219 | break; | ||
1220 | msp3400_dbg("detection still in progress\n"); | ||
1221 | } | ||
1222 | } | ||
1223 | for (i = 0; modelist[i].name != NULL; i++) | ||
1224 | if (modelist[i].retval == val) | ||
1225 | break; | ||
1226 | msp3400_dbg("current mode: %s (0x%04x)\n", | ||
1227 | modelist[i].name ? modelist[i].name : "unknown", | ||
1228 | val); | ||
1229 | msp->main = modelist[i].main; | ||
1230 | msp->second = modelist[i].second; | ||
1231 | |||
1232 | if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { | ||
1233 | /* autodetection has failed, let backup */ | ||
1234 | msp3400_dbg("autodetection failed," | ||
1235 | " switching to backup mode: %s (0x%04x)\n", | ||
1236 | modelist[8].name ? modelist[8].name : "unknown",val); | ||
1237 | val = 0x0009; | ||
1238 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val); | ||
1239 | } | ||
1240 | |||
1241 | /* set various prescales */ | ||
1242 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */ | ||
1243 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */ | ||
1244 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */ | ||
1245 | |||
1246 | /* set stereo */ | ||
1247 | switch (val) { | ||
1248 | case 0x0008: /* B/G NICAM */ | ||
1249 | case 0x000a: /* I NICAM */ | ||
1250 | if (val == 0x0008) | ||
1251 | msp->mode = MSP_MODE_FM_NICAM1; | ||
1252 | else | ||
1253 | msp->mode = MSP_MODE_FM_NICAM2; | ||
1254 | /* just turn on stereo */ | ||
1255 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
1256 | msp->nicam_on = 1; | ||
1257 | msp->watch_stereo = 1; | ||
1258 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); | ||
1259 | break; | ||
1260 | case 0x0009: | ||
1261 | msp->mode = MSP_MODE_AM_NICAM; | ||
1262 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1263 | msp->nicam_on = 1; | ||
1264 | msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); | ||
1265 | msp->watch_stereo = 1; | ||
1266 | break; | ||
1267 | case 0x0020: /* BTSC */ | ||
1268 | /* just turn on stereo */ | ||
1269 | msp->mode = MSP_MODE_BTSC; | ||
1270 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
1271 | msp->nicam_on = 0; | ||
1272 | msp->watch_stereo = 1; | ||
1273 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); | ||
1274 | break; | ||
1275 | case 0x0040: /* FM radio */ | ||
1276 | msp->mode = MSP_MODE_FM_RADIO; | ||
1277 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
1278 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
1279 | msp->nicam_on = 0; | ||
1280 | msp->watch_stereo = 0; | ||
1281 | /* not needed in theory if HAVE_RADIO(), but | ||
1282 | short programming enables carrier mute */ | ||
1283 | msp3400c_setmode(client,MSP_MODE_FM_RADIO); | ||
1284 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | ||
1285 | MSP_CARRIER(10.7)); | ||
1286 | /* scart routing */ | ||
1287 | msp3400c_set_scart(client,SCART_IN2,0); | ||
1288 | /* msp34xx does radio decoding */ | ||
1289 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020); | ||
1290 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020); | ||
1291 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020); | ||
1292 | break; | ||
1293 | case 0x0003: | ||
1294 | case 0x0004: | ||
1295 | case 0x0005: | ||
1296 | msp->mode = MSP_MODE_FM_TERRA; | ||
1297 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1298 | msp->audmode = V4L2_TUNER_MODE_MONO; | ||
1299 | msp->nicam_on = 0; | ||
1300 | msp->watch_stereo = 1; | ||
1301 | break; | ||
1302 | } | ||
1303 | |||
1304 | /* unmute, restore misc registers */ | ||
1305 | msp3400c_setbass(client, msp->bass); | ||
1306 | msp3400c_settreble(client, msp->treble); | ||
1307 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1308 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb); | ||
1309 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1310 | msp3400c_restore_dfp(client); | ||
1311 | |||
1312 | /* monitor tv audio mode */ | ||
1313 | while (msp->watch_stereo) { | ||
1314 | if (msp34xx_sleep(msp,5000)) | ||
1315 | goto restart; | ||
1316 | watch_stereo(client); | ||
1317 | } | ||
1318 | } | ||
1319 | msp3400_dbg("thread: exit\n"); | ||
1320 | return 0; | ||
1321 | } | ||
1322 | |||
1323 | /* ----------------------------------------------------------------------- */ | ||
1324 | /* msp34xxG + (simpler no-thread) */ | ||
1325 | /* this one uses both automatic standard detection and automatic sound */ | ||
1326 | /* select which are available in the newer G versions */ | ||
1327 | /* struct msp: only norm, acb and source are really used in this mode */ | ||
1328 | |||
1329 | static void msp34xxg_set_source(struct i2c_client *client, int source); | ||
1330 | |||
1331 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm | ||
1332 | * return 0 if it worked, -1 if it failed | ||
1333 | */ | ||
1334 | static int msp34xxg_reset(struct i2c_client *client) | ||
1335 | { | ||
1336 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1337 | int modus,std; | ||
1338 | |||
1339 | if (msp3400c_reset(client)) | ||
1340 | return -1; | ||
1341 | |||
1342 | /* make sure that input/output is muted (paranoid mode) */ | ||
1343 | if (msp3400c_write(client, | ||
1344 | I2C_MSP3400C_DFP, | ||
1345 | 0x13, /* ACB */ | ||
1346 | 0x0f20 /* mute DSP input, mute SCART 1 */)) | ||
1347 | return -1; | ||
1348 | |||
1349 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1350 | |||
1351 | /* step-by-step initialisation, as described in the manual */ | ||
1352 | modus = msp34xx_modus(client, msp->norm); | ||
1353 | std = msp34xx_standard(msp->norm); | ||
1354 | modus &= ~0x03; /* STATUS_CHANGE=0 */ | ||
1355 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ | ||
1356 | if (msp3400c_write(client, | ||
1357 | I2C_MSP3400C_DEM, | ||
1358 | 0x30/*MODUS*/, | ||
1359 | modus)) | ||
1360 | return -1; | ||
1361 | if (msp3400c_write(client, | ||
1362 | I2C_MSP3400C_DEM, | ||
1363 | 0x20/*standard*/, | ||
1364 | std)) | ||
1365 | return -1; | ||
1366 | |||
1367 | /* write the dfps that may have an influence on | ||
1368 | standard/audio autodetection right now */ | ||
1369 | msp34xxg_set_source(client, msp->source); | ||
1370 | |||
1371 | if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */ | ||
1372 | 0x3000 | ||
1373 | /* default: [15:8] 75khz deviation */ | ||
1374 | )) | ||
1375 | return -1; | ||
1376 | |||
1377 | if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */ | ||
1378 | 0x5a00 | ||
1379 | /* default: 9db gain (as recommended) */ | ||
1380 | )) | ||
1381 | return -1; | ||
1382 | |||
1383 | return 0; | ||
1384 | } | ||
1385 | |||
1386 | static int msp34xxg_thread(void *data) | ||
1387 | { | ||
1388 | struct i2c_client *client = data; | ||
1389 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1390 | int val, std, i; | ||
1391 | |||
1392 | msp3400_info("msp34xxg daemon started\n"); | ||
1393 | |||
1394 | msp->source = 1; /* default */ | ||
1395 | for (;;) { | ||
1396 | msp3400_dbg_mediumvol("msp34xxg thread: sleep\n"); | ||
1397 | msp34xx_sleep(msp,-1); | ||
1398 | msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n"); | ||
1399 | |||
1400 | restart: | ||
1401 | msp3400_dbg("thread: restart scan\n"); | ||
1402 | msp->restart = 0; | ||
1403 | if (kthread_should_stop()) | ||
1404 | break; | ||
1405 | |||
1406 | /* setup the chip*/ | ||
1407 | msp34xxg_reset(client); | ||
1408 | std = standard; | ||
1409 | if (std != 0x01) | ||
1410 | goto unmute; | ||
1411 | |||
1412 | /* watch autodetect */ | ||
1413 | msp3400_dbg("triggered autodetect, waiting for result\n"); | ||
1414 | for (i = 0; i < 10; i++) { | ||
1415 | if (msp34xx_sleep(msp,100)) | ||
1416 | goto restart; | ||
1417 | |||
1418 | /* check results */ | ||
1419 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); | ||
1420 | if (val < 0x07ff) { | ||
1421 | std = val; | ||
1422 | break; | ||
1423 | } | ||
1424 | msp3400_dbg("detection still in progress\n"); | ||
1425 | } | ||
1426 | if (0x01 == std) { | ||
1427 | msp3400_dbg("detection still in progress after 10 tries. giving up.\n"); | ||
1428 | continue; | ||
1429 | } | ||
1430 | |||
1431 | unmute: | ||
1432 | msp3400_dbg("current mode: %s (0x%04x)\n", | ||
1433 | msp34xx_standard_mode_name(std), std); | ||
1434 | |||
1435 | /* unmute: dispatch sound to scart output, set scart volume */ | ||
1436 | msp3400_dbg("unmute\n"); | ||
1437 | |||
1438 | msp3400c_setbass(client, msp->bass); | ||
1439 | msp3400c_settreble(client, msp->treble); | ||
1440 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1441 | |||
1442 | /* restore ACB */ | ||
1443 | if (msp3400c_write(client, | ||
1444 | I2C_MSP3400C_DFP, | ||
1445 | 0x13, /* ACB */ | ||
1446 | msp->acb)) | ||
1447 | return -1; | ||
1448 | |||
1449 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1450 | } | ||
1451 | msp3400_dbg("thread: exit\n"); | ||
1452 | return 0; | ||
1453 | } | ||
1454 | |||
1455 | /* set the same 'source' for the loudspeaker, scart and quasi-peak detector | ||
1456 | * the value for source is the same as bit 15:8 of DFP registers 0x08, | ||
1457 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B | ||
1458 | * | ||
1459 | * this function replaces msp3400c_setstereo | ||
1460 | */ | ||
1461 | static void msp34xxg_set_source(struct i2c_client *client, int source) | ||
1462 | { | ||
1463 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1464 | |||
1465 | /* fix matrix mode to stereo and let the msp choose what | ||
1466 | * to output according to 'source', as recommended | ||
1467 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
1468 | */ | ||
1469 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); | ||
1470 | msp3400_dbg("set source to %d (0x%x)\n", source, value); | ||
1471 | msp3400c_write(client, | ||
1472 | I2C_MSP3400C_DFP, | ||
1473 | 0x08, /* Loudspeaker Output */ | ||
1474 | value); | ||
1475 | msp3400c_write(client, | ||
1476 | I2C_MSP3400C_DFP, | ||
1477 | 0x0a, /* SCART1 DA Output */ | ||
1478 | value); | ||
1479 | msp3400c_write(client, | ||
1480 | I2C_MSP3400C_DFP, | ||
1481 | 0x0c, /* Quasi-peak detector */ | ||
1482 | value); | ||
1483 | /* | ||
1484 | * set identification threshold. Personally, I | ||
1485 | * I set it to a higher value that the default | ||
1486 | * of 0x190 to ignore noisy stereo signals. | ||
1487 | * this needs tuning. (recommended range 0x00a0-0x03c0) | ||
1488 | * 0x7f0 = forced mono mode | ||
1489 | */ | ||
1490 | msp3400c_write(client, | ||
1491 | I2C_MSP3400C_DEM, | ||
1492 | 0x22, /* a2 threshold for stereo/bilingual */ | ||
1493 | stereo_threshold); | ||
1494 | msp->source=source; | ||
1495 | } | ||
1496 | |||
1497 | static void msp34xxg_detect_stereo(struct i2c_client *client) | ||
1498 | { | ||
1499 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1500 | |||
1501 | int status = msp3400c_read(client, | ||
1502 | I2C_MSP3400C_DEM, | ||
1503 | 0x0200 /* STATUS */); | ||
1504 | int is_bilingual = status&0x100; | ||
1505 | int is_stereo = status&0x40; | ||
1506 | |||
1507 | msp->rxsubchans = 0; | ||
1508 | if (is_stereo) | ||
1509 | msp->rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
1510 | else | ||
1511 | msp->rxsubchans |= V4L2_TUNER_SUB_MONO; | ||
1512 | if (is_bilingual) { | ||
1513 | msp->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2; | ||
1514 | /* I'm supposed to check whether it's SAP or not | ||
1515 | * and set only LANG2/SAP in this case. Yet, the MSP | ||
1516 | * does a lot of work to hide this and handle everything | ||
1517 | * the same way. I don't want to work around it so unless | ||
1518 | * this is a problem, I'll handle SAP just like lang1/lang2. | ||
1519 | */ | ||
1520 | } | ||
1521 | msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", | ||
1522 | status, is_stereo, is_bilingual, msp->rxsubchans); | ||
1523 | } | ||
1524 | |||
1525 | static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | ||
1526 | { | ||
1527 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1528 | int source; | ||
1529 | |||
1530 | switch (audmode) { | ||
1531 | case V4L2_TUNER_MODE_MONO: | ||
1532 | source=0; /* mono only */ | ||
1533 | break; | ||
1534 | case V4L2_TUNER_MODE_STEREO: | ||
1535 | source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ | ||
1536 | /* problem: that could also mean 2 (scart input) */ | ||
1537 | break; | ||
1538 | case V4L2_TUNER_MODE_LANG1: | ||
1539 | source=3; /* stereo or A */ | ||
1540 | break; | ||
1541 | case V4L2_TUNER_MODE_LANG2: | ||
1542 | source=4; /* stereo or B */ | ||
1543 | break; | ||
1544 | default: | ||
1545 | audmode = 0; | ||
1546 | source = 1; | ||
1547 | break; | ||
1548 | } | ||
1549 | msp->audmode = audmode; | ||
1550 | msp34xxg_set_source(client, source); | ||
1551 | } | ||
1552 | |||
1553 | |||
1554 | /* ----------------------------------------------------------------------- */ | ||
1555 | |||
1556 | static int msp_attach(struct i2c_adapter *adap, int addr, int kind); | ||
1557 | static int msp_detach(struct i2c_client *client); | ||
1558 | static int msp_probe(struct i2c_adapter *adap); | ||
1559 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); | ||
1560 | |||
1561 | static int msp_suspend(struct device * dev, pm_message_t state); | ||
1562 | static int msp_resume(struct device * dev); | ||
1563 | |||
1564 | static void msp_wake_thread(struct i2c_client *client); | ||
1565 | |||
1566 | static struct i2c_driver driver = { | ||
1567 | .id = I2C_DRIVERID_MSP3400, | ||
1568 | .attach_adapter = msp_probe, | ||
1569 | .detach_client = msp_detach, | ||
1570 | .command = msp_command, | ||
1571 | .driver = { | ||
1572 | .name = "i2c msp3400 driver", | ||
1573 | .suspend = msp_suspend, | ||
1574 | .resume = msp_resume, | ||
1575 | }, | ||
1576 | }; | ||
1577 | |||
1578 | static struct i2c_client client_template = | ||
1579 | { | ||
1580 | .name = "(unset)", | ||
1581 | .driver = &driver, | ||
1582 | }; | ||
1583 | |||
1584 | static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | ||
1585 | { | ||
1586 | struct msp3400c *msp; | ||
1587 | struct i2c_client *client = &client_template; | ||
1588 | int (*thread_func)(void *data) = NULL; | ||
1589 | int i; | ||
1590 | |||
1591 | client_template.adapter = adap; | ||
1592 | client_template.addr = addr; | ||
1593 | |||
1594 | if (-1 == msp3400c_reset(&client_template)) { | ||
1595 | msp3400_dbg("no chip found\n"); | ||
1596 | return -1; | ||
1597 | } | ||
1598 | |||
1599 | if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) | ||
1600 | return -ENOMEM; | ||
1601 | memcpy(client,&client_template,sizeof(struct i2c_client)); | ||
1602 | if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { | ||
1603 | kfree(client); | ||
1604 | return -ENOMEM; | ||
1605 | } | ||
1606 | |||
1607 | memset(msp,0,sizeof(struct msp3400c)); | ||
1608 | msp->norm = VIDEO_MODE_NTSC; | ||
1609 | msp->left = 58880; /* 0db gain */ | ||
1610 | msp->right = 58880; /* 0db gain */ | ||
1611 | msp->bass = 32768; | ||
1612 | msp->treble = 32768; | ||
1613 | msp->input = -1; | ||
1614 | msp->muted = 0; | ||
1615 | msp->i2s_mode = 0; | ||
1616 | for (i = 0; i < DFP_COUNT; i++) | ||
1617 | msp->dfp_regs[i] = -1; | ||
1618 | |||
1619 | i2c_set_clientdata(client, msp); | ||
1620 | init_waitqueue_head(&msp->wq); | ||
1621 | |||
1622 | if (-1 == msp3400c_reset(client)) { | ||
1623 | kfree(msp); | ||
1624 | kfree(client); | ||
1625 | msp3400_dbg("no chip found\n"); | ||
1626 | return -1; | ||
1627 | } | ||
1628 | |||
1629 | msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e); | ||
1630 | if (-1 != msp->rev1) | ||
1631 | msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f); | ||
1632 | if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { | ||
1633 | kfree(msp); | ||
1634 | kfree(client); | ||
1635 | msp3400_dbg("error while reading chip version\n"); | ||
1636 | return -1; | ||
1637 | } | ||
1638 | msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2); | ||
1639 | |||
1640 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1641 | |||
1642 | snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", | ||
1643 | ((msp->rev1>>4)&0x0f) + '3', | ||
1644 | (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@', | ||
1645 | ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); | ||
1646 | |||
1647 | msp->opmode = opmode; | ||
1648 | if (OPMODE_AUTO == msp->opmode) { | ||
1649 | if (HAVE_SIMPLER(msp)) | ||
1650 | msp->opmode = OPMODE_SIMPLER; | ||
1651 | else if (HAVE_SIMPLE(msp)) | ||
1652 | msp->opmode = OPMODE_SIMPLE; | ||
1653 | else | ||
1654 | msp->opmode = OPMODE_MANUAL; | ||
1655 | } | ||
1656 | |||
1657 | /* hello world :-) */ | ||
1658 | msp3400_info("chip=%s", client->name); | ||
1659 | if (HAVE_NICAM(msp)) | ||
1660 | printk(" +nicam"); | ||
1661 | if (HAVE_SIMPLE(msp)) | ||
1662 | printk(" +simple"); | ||
1663 | if (HAVE_SIMPLER(msp)) | ||
1664 | printk(" +simpler"); | ||
1665 | if (HAVE_RADIO(msp)) | ||
1666 | printk(" +radio"); | ||
1667 | |||
1668 | /* version-specific initialization */ | ||
1669 | switch (msp->opmode) { | ||
1670 | case OPMODE_MANUAL: | ||
1671 | printk(" mode=manual"); | ||
1672 | thread_func = msp3400c_thread; | ||
1673 | break; | ||
1674 | case OPMODE_SIMPLE: | ||
1675 | printk(" mode=simple"); | ||
1676 | thread_func = msp3410d_thread; | ||
1677 | break; | ||
1678 | case OPMODE_SIMPLER: | ||
1679 | printk(" mode=simpler"); | ||
1680 | thread_func = msp34xxg_thread; | ||
1681 | break; | ||
1682 | } | ||
1683 | printk("\n"); | ||
1684 | |||
1685 | /* startup control thread if needed */ | ||
1686 | if (thread_func) { | ||
1687 | msp->kthread = kthread_run(thread_func, client, "msp34xx"); | ||
1688 | |||
1689 | if (NULL == msp->kthread) | ||
1690 | msp3400_warn("kernel_thread() failed\n"); | ||
1691 | msp_wake_thread(client); | ||
1692 | } | ||
1693 | |||
1694 | /* done */ | ||
1695 | i2c_attach_client(client); | ||
1696 | |||
1697 | /* update our own array */ | ||
1698 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1699 | if (NULL == msps[i]) { | ||
1700 | msps[i] = client; | ||
1701 | break; | ||
1702 | } | ||
1703 | } | ||
1704 | |||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1708 | static int msp_detach(struct i2c_client *client) | ||
1709 | { | ||
1710 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1711 | int i; | ||
1712 | |||
1713 | /* shutdown control thread */ | ||
1714 | if (msp->kthread) { | ||
1715 | msp->restart = 1; | ||
1716 | kthread_stop(msp->kthread); | ||
1717 | } | ||
1718 | msp3400c_reset(client); | ||
1719 | |||
1720 | /* update our own array */ | ||
1721 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1722 | if (client == msps[i]) { | ||
1723 | msps[i] = NULL; | ||
1724 | break; | ||
1725 | } | ||
1726 | } | ||
1727 | |||
1728 | i2c_detach_client(client); | ||
1729 | |||
1730 | kfree(msp); | ||
1731 | kfree(client); | ||
1732 | return 0; | ||
1733 | } | ||
1734 | |||
1735 | static int msp_probe(struct i2c_adapter *adap) | ||
1736 | { | ||
1737 | if (adap->class & I2C_CLASS_TV_ANALOG) | ||
1738 | return i2c_probe(adap, &addr_data, msp_attach); | ||
1739 | return 0; | ||
1740 | } | ||
1741 | |||
1742 | static void msp_wake_thread(struct i2c_client *client) | ||
1743 | { | ||
1744 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1745 | |||
1746 | if (NULL == msp->kthread) | ||
1747 | return; | ||
1748 | msp3400c_setvolume(client,msp->muted,0,0); | ||
1749 | msp->watch_stereo = 0; | ||
1750 | msp->restart = 1; | ||
1751 | wake_up_interruptible(&msp->wq); | ||
1752 | } | ||
1753 | |||
1754 | /* ----------------------------------------------------------------------- */ | ||
1755 | |||
1756 | static int mode_v4l2_to_v4l1(int rxsubchans) | ||
1757 | { | ||
1758 | int mode = 0; | ||
1759 | |||
1760 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
1761 | mode |= VIDEO_SOUND_STEREO; | ||
1762 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) | ||
1763 | mode |= VIDEO_SOUND_LANG2; | ||
1764 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | ||
1765 | mode |= VIDEO_SOUND_LANG1; | ||
1766 | if (0 == mode) | ||
1767 | mode |= VIDEO_SOUND_MONO; | ||
1768 | return mode; | ||
1769 | } | ||
1770 | |||
1771 | static int mode_v4l1_to_v4l2(int mode) | ||
1772 | { | ||
1773 | if (mode & VIDEO_SOUND_STEREO) | ||
1774 | return V4L2_TUNER_MODE_STEREO; | ||
1775 | if (mode & VIDEO_SOUND_LANG2) | ||
1776 | return V4L2_TUNER_MODE_LANG2; | ||
1777 | if (mode & VIDEO_SOUND_LANG1) | ||
1778 | return V4L2_TUNER_MODE_LANG1; | ||
1779 | return V4L2_TUNER_MODE_MONO; | ||
1780 | } | ||
1781 | |||
1782 | static void msp_any_detect_stereo(struct i2c_client *client) | ||
1783 | { | ||
1784 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1785 | |||
1786 | switch (msp->opmode) { | ||
1787 | case OPMODE_MANUAL: | ||
1788 | case OPMODE_SIMPLE: | ||
1789 | autodetect_stereo(client); | ||
1790 | break; | ||
1791 | case OPMODE_SIMPLER: | ||
1792 | msp34xxg_detect_stereo(client); | ||
1793 | break; | ||
1794 | } | ||
1795 | } | ||
1796 | |||
1797 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) | ||
1798 | { | ||
1799 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1800 | |||
1801 | switch (msp->opmode) { | ||
1802 | case OPMODE_MANUAL: | ||
1803 | case OPMODE_SIMPLE: | ||
1804 | msp->watch_stereo = 0; | ||
1805 | msp3400c_setstereo(client, audmode); | ||
1806 | break; | ||
1807 | case OPMODE_SIMPLER: | ||
1808 | msp34xxg_set_audmode(client, audmode); | ||
1809 | break; | ||
1810 | } | ||
1811 | } | ||
1812 | |||
1813 | |||
1814 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | ||
1815 | { | ||
1816 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1817 | __u16 *sarg = arg; | ||
1818 | int scart = 0; | ||
1819 | |||
1820 | switch (cmd) { | ||
1821 | |||
1822 | case AUDC_SET_INPUT: | ||
1823 | msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg); | ||
1824 | |||
1825 | if (*sarg == msp->input) | ||
1826 | break; | ||
1827 | msp->input = *sarg; | ||
1828 | switch (*sarg) { | ||
1829 | case AUDIO_RADIO: | ||
1830 | /* Hauppauge uses IN2 for the radio */ | ||
1831 | msp->mode = MSP_MODE_FM_RADIO; | ||
1832 | scart = SCART_IN2; | ||
1833 | break; | ||
1834 | case AUDIO_EXTERN_1: | ||
1835 | /* IN1 is often used for external input ... */ | ||
1836 | msp->mode = MSP_MODE_EXTERN; | ||
1837 | scart = SCART_IN1; | ||
1838 | break; | ||
1839 | case AUDIO_EXTERN_2: | ||
1840 | /* ... sometimes it is IN2 through ;) */ | ||
1841 | msp->mode = MSP_MODE_EXTERN; | ||
1842 | scart = SCART_IN2; | ||
1843 | break; | ||
1844 | case AUDIO_TUNER: | ||
1845 | msp->mode = -1; | ||
1846 | break; | ||
1847 | default: | ||
1848 | if (*sarg & AUDIO_MUTE) | ||
1849 | msp3400c_set_scart(client,SCART_MUTE,0); | ||
1850 | break; | ||
1851 | } | ||
1852 | if (scart) { | ||
1853 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
1854 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
1855 | msp3400c_set_scart(client,scart,0); | ||
1856 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); | ||
1857 | if (msp->opmode != OPMODE_SIMPLER) | ||
1858 | msp3400c_setstereo(client, msp->audmode); | ||
1859 | } | ||
1860 | msp_wake_thread(client); | ||
1861 | break; | ||
1862 | |||
1863 | case AUDC_SET_RADIO: | ||
1864 | msp3400_dbg("AUDC_SET_RADIO\n"); | ||
1865 | msp->norm = VIDEO_MODE_RADIO; | ||
1866 | msp3400_dbg("switching to radio mode\n"); | ||
1867 | msp->watch_stereo = 0; | ||
1868 | switch (msp->opmode) { | ||
1869 | case OPMODE_MANUAL: | ||
1870 | /* set msp3400 to FM radio mode */ | ||
1871 | msp3400c_setmode(client,MSP_MODE_FM_RADIO); | ||
1872 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | ||
1873 | MSP_CARRIER(10.7)); | ||
1874 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1875 | break; | ||
1876 | case OPMODE_SIMPLE: | ||
1877 | case OPMODE_SIMPLER: | ||
1878 | /* the thread will do for us */ | ||
1879 | msp_wake_thread(client); | ||
1880 | break; | ||
1881 | } | ||
1882 | break; | ||
1883 | /* work-in-progress: hook to control the DFP registers */ | ||
1884 | case MSP_SET_DFPREG: | ||
1885 | { | ||
1886 | struct msp_dfpreg *r = arg; | ||
1887 | int i; | ||
1888 | |||
1889 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1890 | return -EINVAL; | ||
1891 | for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++) | ||
1892 | if (r->reg == bl_dfp[i]) | ||
1893 | return -EINVAL; | ||
1894 | msp->dfp_regs[r->reg] = r->value; | ||
1895 | msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value); | ||
1896 | return 0; | ||
1897 | } | ||
1898 | case MSP_GET_DFPREG: | ||
1899 | { | ||
1900 | struct msp_dfpreg *r = arg; | ||
1901 | |||
1902 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1903 | return -EINVAL; | ||
1904 | r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg); | ||
1905 | return 0; | ||
1906 | } | ||
1907 | |||
1908 | /* --- v4l ioctls --- */ | ||
1909 | /* take care: bttv does userspace copying, we'll get a | ||
1910 | kernel pointer here... */ | ||
1911 | case VIDIOCGAUDIO: | ||
1912 | { | ||
1913 | struct video_audio *va = arg; | ||
1914 | |||
1915 | msp3400_dbg("VIDIOCGAUDIO\n"); | ||
1916 | va->flags |= VIDEO_AUDIO_VOLUME | | ||
1917 | VIDEO_AUDIO_BASS | | ||
1918 | VIDEO_AUDIO_TREBLE | | ||
1919 | VIDEO_AUDIO_MUTABLE; | ||
1920 | if (msp->muted) | ||
1921 | va->flags |= VIDEO_AUDIO_MUTE; | ||
1922 | |||
1923 | if (msp->muted) | ||
1924 | va->flags |= VIDEO_AUDIO_MUTE; | ||
1925 | va->volume = MAX(msp->left, msp->right); | ||
1926 | va->balance = (32768 * MIN(msp->left, msp->right)) / | ||
1927 | (va->volume ? va->volume : 1); | ||
1928 | va->balance = (msp->left < msp->right) ? | ||
1929 | (65535 - va->balance) : va->balance; | ||
1930 | if (0 == va->volume) | ||
1931 | va->balance = 32768; | ||
1932 | va->bass = msp->bass; | ||
1933 | va->treble = msp->treble; | ||
1934 | |||
1935 | msp_any_detect_stereo(client); | ||
1936 | va->mode = mode_v4l2_to_v4l1(msp->rxsubchans); | ||
1937 | break; | ||
1938 | } | ||
1939 | case VIDIOCSAUDIO: | ||
1940 | { | ||
1941 | struct video_audio *va = arg; | ||
1942 | |||
1943 | msp3400_dbg("VIDIOCSAUDIO\n"); | ||
1944 | msp->muted = (va->flags & VIDEO_AUDIO_MUTE); | ||
1945 | msp->left = (MIN(65536 - va->balance, 32768) * | ||
1946 | va->volume) / 32768; | ||
1947 | msp->right = (MIN(va->balance, 32768) * va->volume) / 32768; | ||
1948 | msp->bass = va->bass; | ||
1949 | msp->treble = va->treble; | ||
1950 | msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n", | ||
1951 | va->volume); | ||
1952 | msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n", | ||
1953 | va->balance); | ||
1954 | msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n", | ||
1955 | va->flags); | ||
1956 | msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n", | ||
1957 | msp->left); | ||
1958 | msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n", | ||
1959 | msp->right); | ||
1960 | msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n", | ||
1961 | msp->bass); | ||
1962 | msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n", | ||
1963 | msp->treble); | ||
1964 | msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n", | ||
1965 | msp->mode); | ||
1966 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1967 | msp3400c_setbass(client, msp->bass); | ||
1968 | msp3400c_settreble(client, msp->treble); | ||
1969 | |||
1970 | if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) | ||
1971 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); | ||
1972 | break; | ||
1973 | } | ||
1974 | |||
1975 | case VIDIOCSCHAN: | ||
1976 | { | ||
1977 | struct video_channel *vc = arg; | ||
1978 | |||
1979 | msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm); | ||
1980 | msp->norm = vc->norm; | ||
1981 | msp_wake_thread(client); | ||
1982 | break; | ||
1983 | } | ||
1984 | |||
1985 | case VIDIOCSFREQ: | ||
1986 | case VIDIOC_S_FREQUENCY: | ||
1987 | { | ||
1988 | /* new channel -- kick audio carrier scan */ | ||
1989 | msp3400_dbg("VIDIOCSFREQ\n"); | ||
1990 | msp_wake_thread(client); | ||
1991 | break; | ||
1992 | } | ||
1993 | |||
1994 | /* msp34xx specific */ | ||
1995 | case MSP_SET_MATRIX: | ||
1996 | { | ||
1997 | struct msp_matrix *mspm = arg; | ||
1998 | |||
1999 | msp3400_dbg("MSP_SET_MATRIX\n"); | ||
2000 | msp3400c_set_scart(client, mspm->input, mspm->output); | ||
2001 | break; | ||
2002 | } | ||
2003 | |||
2004 | /* --- v4l2 ioctls --- */ | ||
2005 | case VIDIOC_S_STD: | ||
2006 | { | ||
2007 | v4l2_std_id *id = arg; | ||
2008 | |||
2009 | /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ | ||
2010 | if (*id & V4L2_STD_PAL) { | ||
2011 | msp->norm=VIDEO_MODE_PAL; | ||
2012 | } else if (*id & V4L2_STD_SECAM) { | ||
2013 | msp->norm=VIDEO_MODE_SECAM; | ||
2014 | } else { | ||
2015 | msp->norm=VIDEO_MODE_NTSC; | ||
2016 | } | ||
2017 | |||
2018 | msp_wake_thread(client); | ||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
2022 | case VIDIOC_ENUMINPUT: | ||
2023 | { | ||
2024 | struct v4l2_input *i = arg; | ||
2025 | |||
2026 | if (i->index != 0) | ||
2027 | return -EINVAL; | ||
2028 | |||
2029 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
2030 | switch (i->index) { | ||
2031 | case AUDIO_RADIO: | ||
2032 | strcpy(i->name,"Radio"); | ||
2033 | break; | ||
2034 | case AUDIO_EXTERN_1: | ||
2035 | strcpy(i->name,"Extern 1"); | ||
2036 | break; | ||
2037 | case AUDIO_EXTERN_2: | ||
2038 | strcpy(i->name,"Extern 2"); | ||
2039 | break; | ||
2040 | case AUDIO_TUNER: | ||
2041 | strcpy(i->name,"Television"); | ||
2042 | break; | ||
2043 | default: | ||
2044 | return -EINVAL; | ||
2045 | } | ||
2046 | return 0; | ||
2047 | } | ||
2048 | |||
2049 | case VIDIOC_G_AUDIO: | ||
2050 | { | ||
2051 | struct v4l2_audio *a = arg; | ||
2052 | |||
2053 | memset(a,0,sizeof(*a)); | ||
2054 | |||
2055 | switch (a->index) { | ||
2056 | case AUDIO_RADIO: | ||
2057 | strcpy(a->name,"Radio"); | ||
2058 | break; | ||
2059 | case AUDIO_EXTERN_1: | ||
2060 | strcpy(a->name,"Extern 1"); | ||
2061 | break; | ||
2062 | case AUDIO_EXTERN_2: | ||
2063 | strcpy(a->name,"Extern 2"); | ||
2064 | break; | ||
2065 | case AUDIO_TUNER: | ||
2066 | strcpy(a->name,"Television"); | ||
2067 | break; | ||
2068 | default: | ||
2069 | return -EINVAL; | ||
2070 | } | ||
2071 | |||
2072 | msp_any_detect_stereo(client); | ||
2073 | if (msp->audmode == V4L2_TUNER_MODE_STEREO) { | ||
2074 | a->capability=V4L2_AUDCAP_STEREO; | ||
2075 | } | ||
2076 | |||
2077 | break; | ||
2078 | } | ||
2079 | case VIDIOC_S_AUDIO: | ||
2080 | { | ||
2081 | struct v4l2_audio *sarg = arg; | ||
2082 | |||
2083 | switch (sarg->index) { | ||
2084 | case AUDIO_RADIO: | ||
2085 | /* Hauppauge uses IN2 for the radio */ | ||
2086 | msp->mode = MSP_MODE_FM_RADIO; | ||
2087 | scart = SCART_IN2; | ||
2088 | break; | ||
2089 | case AUDIO_EXTERN_1: | ||
2090 | /* IN1 is often used for external input ... */ | ||
2091 | msp->mode = MSP_MODE_EXTERN; | ||
2092 | scart = SCART_IN1; | ||
2093 | break; | ||
2094 | case AUDIO_EXTERN_2: | ||
2095 | /* ... sometimes it is IN2 through ;) */ | ||
2096 | msp->mode = MSP_MODE_EXTERN; | ||
2097 | scart = SCART_IN2; | ||
2098 | break; | ||
2099 | case AUDIO_TUNER: | ||
2100 | msp->mode = -1; | ||
2101 | break; | ||
2102 | } | ||
2103 | if (scart) { | ||
2104 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
2105 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
2106 | msp3400c_set_scart(client,scart,0); | ||
2107 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); | ||
2108 | } | ||
2109 | if (sarg->capability==V4L2_AUDCAP_STEREO) { | ||
2110 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
2111 | } else { | ||
2112 | msp->audmode &= ~V4L2_TUNER_MODE_STEREO; | ||
2113 | } | ||
2114 | msp_any_set_audmode(client, msp->audmode); | ||
2115 | msp_wake_thread(client); | ||
2116 | break; | ||
2117 | } | ||
2118 | case VIDIOC_G_TUNER: | ||
2119 | { | ||
2120 | struct v4l2_tuner *vt = arg; | ||
2121 | |||
2122 | msp_any_detect_stereo(client); | ||
2123 | vt->audmode = msp->audmode; | ||
2124 | vt->rxsubchans = msp->rxsubchans; | ||
2125 | vt->capability = V4L2_TUNER_CAP_STEREO | | ||
2126 | V4L2_TUNER_CAP_LANG1| | ||
2127 | V4L2_TUNER_CAP_LANG2; | ||
2128 | break; | ||
2129 | } | ||
2130 | case VIDIOC_S_TUNER: | ||
2131 | { | ||
2132 | struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; | ||
2133 | |||
2134 | /* only set audmode */ | ||
2135 | if (vt->audmode != -1 && vt->audmode != 0) | ||
2136 | msp_any_set_audmode(client, vt->audmode); | ||
2137 | break; | ||
2138 | } | ||
2139 | |||
2140 | case VIDIOC_G_AUDOUT: | ||
2141 | { | ||
2142 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; | ||
2143 | int idx=a->index; | ||
2144 | |||
2145 | memset(a,0,sizeof(*a)); | ||
2146 | |||
2147 | switch (idx) { | ||
2148 | case 0: | ||
2149 | strcpy(a->name,"Scart1 Out"); | ||
2150 | break; | ||
2151 | case 1: | ||
2152 | strcpy(a->name,"Scart2 Out"); | ||
2153 | break; | ||
2154 | case 2: | ||
2155 | strcpy(a->name,"I2S Out"); | ||
2156 | break; | ||
2157 | default: | ||
2158 | return -EINVAL; | ||
2159 | } | ||
2160 | break; | ||
2161 | |||
2162 | } | ||
2163 | case VIDIOC_S_AUDOUT: | ||
2164 | { | ||
2165 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; | ||
2166 | |||
2167 | if (a->index<0||a->index>2) | ||
2168 | return -EINVAL; | ||
2169 | |||
2170 | if (a->index==2) { | ||
2171 | if (a->mode == V4L2_AUDMODE_32BITS) | ||
2172 | msp->i2s_mode=1; | ||
2173 | else | ||
2174 | msp->i2s_mode=0; | ||
2175 | } | ||
2176 | msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n", | ||
2177 | a->index,msp->i2s_mode); | ||
2178 | msp3400c_set_scart(client,msp->in_scart,a->index+1); | ||
2179 | |||
2180 | break; | ||
2181 | } | ||
2182 | |||
2183 | default: | ||
2184 | /* nothing */ | ||
2185 | break; | ||
2186 | } | ||
2187 | return 0; | ||
2188 | } | ||
2189 | |||
2190 | static int msp_suspend(struct device * dev, pm_message_t state) | ||
2191 | { | ||
2192 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | ||
2193 | |||
2194 | msp3400_dbg("msp34xx: suspend\n"); | ||
2195 | msp3400c_reset(client); | ||
2196 | return 0; | ||
2197 | } | ||
2198 | |||
2199 | static int msp_resume(struct device * dev) | ||
2200 | { | ||
2201 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | ||
2202 | |||
2203 | msp3400_dbg("msp34xx: resume\n"); | ||
2204 | msp_wake_thread(client); | ||
2205 | return 0; | ||
2206 | } | ||
2207 | |||
2208 | /* ----------------------------------------------------------------------- */ | ||
2209 | |||
2210 | static int __init msp3400_init_module(void) | ||
2211 | { | ||
2212 | return i2c_add_driver(&driver); | ||
2213 | } | ||
2214 | |||
2215 | static void __exit msp3400_cleanup_module(void) | ||
2216 | { | ||
2217 | i2c_del_driver(&driver); | ||
2218 | } | ||
2219 | |||
2220 | module_init(msp3400_init_module); | ||
2221 | module_exit(msp3400_cleanup_module); | ||
2222 | |||
2223 | /* | ||
2224 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
2225 | * --------------------------------------------------------------------------- | ||
2226 | * Local variables: | ||
2227 | * c-basic-offset: 8 | ||
2228 | * End: | ||
2229 | */ | ||
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h index 2d9ff40f0b09..8a05cf500a8c 100644 --- a/drivers/media/video/msp3400.h +++ b/drivers/media/video/msp3400.h | |||
@@ -6,22 +6,28 @@ | |||
6 | 6 | ||
7 | /* ---------------------------------------------------------------------- */ | 7 | /* ---------------------------------------------------------------------- */ |
8 | 8 | ||
9 | struct msp_dfpreg { | ||
10 | int reg; | ||
11 | int value; | ||
12 | }; | ||
13 | |||
14 | struct msp_matrix { | 9 | struct msp_matrix { |
15 | int input; | 10 | int input; |
16 | int output; | 11 | int output; |
17 | }; | 12 | }; |
18 | 13 | ||
19 | #define MSP_SET_DFPREG _IOW('m',15,struct msp_dfpreg) | ||
20 | #define MSP_GET_DFPREG _IOW('m',16,struct msp_dfpreg) | ||
21 | |||
22 | /* ioctl for MSP_SET_MATRIX will have to be registered */ | 14 | /* ioctl for MSP_SET_MATRIX will have to be registered */ |
23 | #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) | 15 | #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) |
24 | 16 | ||
17 | /* This macro is allowed for *constants* only, gcc must calculate it | ||
18 | at compile time. Remember -- no floats in kernel mode */ | ||
19 | #define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24))) | ||
20 | |||
21 | #define MSP_MODE_AM_DETECT 0 | ||
22 | #define MSP_MODE_FM_RADIO 2 | ||
23 | #define MSP_MODE_FM_TERRA 3 | ||
24 | #define MSP_MODE_FM_SAT 4 | ||
25 | #define MSP_MODE_FM_NICAM1 5 | ||
26 | #define MSP_MODE_FM_NICAM2 6 | ||
27 | #define MSP_MODE_AM_NICAM 7 | ||
28 | #define MSP_MODE_BTSC 8 | ||
29 | #define MSP_MODE_EXTERN 9 | ||
30 | |||
25 | #define SCART_MASK 0 | 31 | #define SCART_MASK 0 |
26 | #define SCART_IN1 1 | 32 | #define SCART_IN1 1 |
27 | #define SCART_IN2 2 | 33 | #define SCART_IN2 2 |
@@ -36,4 +42,84 @@ struct msp_matrix { | |||
36 | #define SCART1_OUT 1 | 42 | #define SCART1_OUT 1 |
37 | #define SCART2_OUT 2 | 43 | #define SCART2_OUT 2 |
38 | 44 | ||
45 | #define OPMODE_AUTO -1 | ||
46 | #define OPMODE_MANUAL 0 | ||
47 | #define OPMODE_AUTODETECT 1 /* use autodetect (>= msp3410 only) */ | ||
48 | #define OPMODE_AUTOSELECT 2 /* use autodetect & autoselect (>= msp34xxG) */ | ||
49 | |||
50 | /* module parameters */ | ||
51 | extern int debug; | ||
52 | extern int once; | ||
53 | extern int amsound; | ||
54 | extern int standard; | ||
55 | extern int dolby; | ||
56 | extern int stereo_threshold; | ||
57 | |||
58 | struct msp_state { | ||
59 | int rev1, rev2; | ||
60 | u8 has_nicam; | ||
61 | u8 has_radio; | ||
62 | u8 has_headphones; | ||
63 | u8 has_ntsc_jp_d_k3; | ||
64 | u8 has_scart4; | ||
65 | u8 has_scart23_in_scart2_out; | ||
66 | u8 has_scart2_out_volume; | ||
67 | u8 has_i2s_conf; | ||
68 | u8 has_subwoofer; | ||
69 | u8 has_sound_processing; | ||
70 | u8 has_virtual_dolby_surround; | ||
71 | u8 has_dolby_pro_logic; | ||
72 | |||
73 | int radio; | ||
74 | int opmode; | ||
75 | int std; | ||
76 | int mode; | ||
77 | v4l2_std_id v4l2_std; | ||
78 | int nicam_on; | ||
79 | int acb; | ||
80 | int in_scart; | ||
81 | int i2s_mode; | ||
82 | int main, second; /* sound carrier */ | ||
83 | int input; | ||
84 | int source; /* see msp34xxg_set_source */ | ||
85 | |||
86 | /* v4l2 */ | ||
87 | int audmode; | ||
88 | int rxsubchans; | ||
89 | |||
90 | int volume, muted; | ||
91 | int balance, loudness; | ||
92 | int bass, treble; | ||
93 | |||
94 | /* thread */ | ||
95 | struct task_struct *kthread; | ||
96 | wait_queue_head_t wq; | ||
97 | int restart:1; | ||
98 | int watch_stereo:1; | ||
99 | }; | ||
100 | |||
101 | /* msp3400-driver.c */ | ||
102 | int msp_write_dem(struct i2c_client *client, int addr, int val); | ||
103 | int msp_write_dsp(struct i2c_client *client, int addr, int val); | ||
104 | int msp_read_dem(struct i2c_client *client, int addr); | ||
105 | int msp_read_dsp(struct i2c_client *client, int addr); | ||
106 | int msp_reset(struct i2c_client *client); | ||
107 | void msp_set_scart(struct i2c_client *client, int in, int out); | ||
108 | void msp_set_mute(struct i2c_client *client); | ||
109 | void msp_set_audio(struct i2c_client *client); | ||
110 | int msp_modus(struct i2c_client *client); | ||
111 | int msp_sleep(struct msp_state *state, int timeout); | ||
112 | |||
113 | /* msp3400-kthreads.c */ | ||
114 | const char *msp_standard_std_name(int std); | ||
115 | void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2); | ||
116 | void msp3400c_setmode(struct i2c_client *client, int type); | ||
117 | void msp3400c_setstereo(struct i2c_client *client, int mode); | ||
118 | int autodetect_stereo(struct i2c_client *client); | ||
119 | int msp3400c_thread(void *data); | ||
120 | int msp3410d_thread(void *data); | ||
121 | int msp34xxg_thread(void *data); | ||
122 | void msp34xxg_detect_stereo(struct i2c_client *client); | ||
123 | void msp34xxg_set_audmode(struct i2c_client *client, int audmode); | ||
124 | |||
39 | #endif /* MSP3400_H */ | 125 | #endif /* MSP3400_H */ |
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 2180018f06de..2c19c9588c02 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
@@ -20,6 +20,9 @@ module_param(tv_antenna, int, 0644); | |||
20 | static unsigned int radio_antenna = 0; | 20 | static unsigned int radio_antenna = 0; |
21 | module_param(radio_antenna, int, 0644); | 21 | module_param(radio_antenna, int, 0644); |
22 | 22 | ||
23 | /* from tuner-core.c */ | ||
24 | extern int debug; | ||
25 | |||
23 | /* ---------------------------------------------------------------------- */ | 26 | /* ---------------------------------------------------------------------- */ |
24 | 27 | ||
25 | #define MT2032 0x04 | 28 | #define MT2032 0x04 |
@@ -401,7 +404,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned | |||
401 | div2a=(lo2/8)-1; | 404 | div2a=(lo2/8)-1; |
402 | div2b=lo2-(div2a+1)*8; | 405 | div2b=lo2-(div2a+1)*8; |
403 | 406 | ||
404 | if (tuner_debug > 1) { | 407 | if (debug > 1) { |
405 | tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); | 408 | tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); |
406 | tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", | 409 | tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", |
407 | num1,num2,div1a,div1b,div2a,div2b); | 410 | num1,num2,div1a,div1b,div2a,div2b); |
@@ -417,7 +420,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned | |||
417 | buf[5]=div2a; | 420 | buf[5]=div2a; |
418 | if(num2!=0) buf[5]=buf[5]|0x40; | 421 | if(num2!=0) buf[5]=buf[5]|0x40; |
419 | 422 | ||
420 | if (tuner_debug > 1) { | 423 | if (debug > 1) { |
421 | int i; | 424 | int i; |
422 | tuner_dbg("bufs is: "); | 425 | tuner_dbg("bufs is: "); |
423 | for(i=0;i<6;i++) | 426 | for(i=0;i<6;i++) |
@@ -494,11 +497,18 @@ int microtune_init(struct i2c_client *c) | |||
494 | t->tv_freq = NULL; | 497 | t->tv_freq = NULL; |
495 | t->radio_freq = NULL; | 498 | t->radio_freq = NULL; |
496 | t->standby = NULL; | 499 | t->standby = NULL; |
500 | if (t->std & V4L2_STD_525_60) { | ||
501 | tuner_dbg("pinnacle ntsc\n"); | ||
502 | t->radio_if2 = 41300 * 1000; | ||
503 | } else { | ||
504 | tuner_dbg("pinnacle pal\n"); | ||
505 | t->radio_if2 = 33300 * 1000; | ||
506 | } | ||
497 | name = "unknown"; | 507 | name = "unknown"; |
498 | 508 | ||
499 | i2c_master_send(c,buf,1); | 509 | i2c_master_send(c,buf,1); |
500 | i2c_master_recv(c,buf,21); | 510 | i2c_master_recv(c,buf,21); |
501 | if (tuner_debug) { | 511 | if (debug) { |
502 | int i; | 512 | int i; |
503 | tuner_dbg("MT20xx hexdump:"); | 513 | tuner_dbg("MT20xx hexdump:"); |
504 | for(i=0;i<21;i++) { | 514 | for(i=0;i<21;i++) { |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index d04793fb80fc..91681aa6c657 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <media/saa7146_vv.h> | 26 | #include <media/saa7146_vv.h> |
27 | #include <media/tuner.h> | 27 | #include <media/tuner.h> |
28 | #include <linux/video_decoder.h> | 28 | #include <linux/video_decoder.h> |
29 | #include <media/v4l2-common.h> | ||
29 | 30 | ||
30 | #include "mxb.h" | 31 | #include "mxb.h" |
31 | #include "tea6415c.h" | 32 | #include "tea6415c.h" |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 2504207b2e3d..9e6448639480 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
@@ -883,6 +883,7 @@ static struct file_operations pms_fops = { | |||
883 | .open = video_exclusive_open, | 883 | .open = video_exclusive_open, |
884 | .release = video_exclusive_release, | 884 | .release = video_exclusive_release, |
885 | .ioctl = pms_ioctl, | 885 | .ioctl = pms_ioctl, |
886 | .compat_ioctl = v4l_compat_ioctl32, | ||
886 | .read = pms_read, | 887 | .read = pms_read, |
887 | .llseek = no_llseek, | 888 | .llseek = no_llseek, |
888 | }; | 889 | }; |
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index a51c7bd96618..73b4f0e2abf0 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
@@ -702,6 +702,7 @@ static struct file_operations saa_fops = { | |||
702 | .open = saa5249_open, | 702 | .open = saa5249_open, |
703 | .release = saa5249_release, | 703 | .release = saa5249_release, |
704 | .ioctl = saa5249_ioctl, | 704 | .ioctl = saa5249_ioctl, |
705 | .compat_ioctl = v4l_compat_ioctl32, | ||
705 | .llseek = no_llseek, | 706 | .llseek = no_llseek, |
706 | }; | 707 | }; |
707 | 708 | ||
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index d60a783e0473..e70b17ef36e9 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -427,18 +427,8 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) | |||
427 | 427 | ||
428 | static int saa6588_probe(struct i2c_adapter *adap) | 428 | static int saa6588_probe(struct i2c_adapter *adap) |
429 | { | 429 | { |
430 | #ifdef I2C_CLASS_TV_ANALOG | ||
431 | if (adap->class & I2C_CLASS_TV_ANALOG) | 430 | if (adap->class & I2C_CLASS_TV_ANALOG) |
432 | return i2c_probe(adap, &addr_data, saa6588_attach); | 431 | return i2c_probe(adap, &addr_data, saa6588_attach); |
433 | #else | ||
434 | switch (adap->id) { | ||
435 | case I2C_HW_B_BT848: | ||
436 | case I2C_HW_B_RIVA: | ||
437 | case I2C_HW_SAA7134: | ||
438 | return i2c_probe(adap, &addr_data, saa6588_attach); | ||
439 | break; | ||
440 | } | ||
441 | #endif | ||
442 | return 0; | 432 | return 0; |
443 | } | 433 | } |
444 | 434 | ||
@@ -496,7 +486,7 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd, | |||
496 | 486 | ||
497 | static struct i2c_driver driver = { | 487 | static struct i2c_driver driver = { |
498 | .driver = { | 488 | .driver = { |
499 | .name = "i2c saa6588 driver", | 489 | .name = "saa6588", |
500 | }, | 490 | }, |
501 | .id = -1, /* FIXME */ | 491 | .id = -1, /* FIXME */ |
502 | .attach_adapter = saa6588_probe, | 492 | .attach_adapter = saa6588_probe, |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 29e28c742cd4..4a4bc69fb0e9 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -39,31 +39,18 @@ | |||
39 | #include <linux/i2c.h> | 39 | #include <linux/i2c.h> |
40 | #include <linux/videodev2.h> | 40 | #include <linux/videodev2.h> |
41 | #include <media/v4l2-common.h> | 41 | #include <media/v4l2-common.h> |
42 | #include <media/audiochip.h> | ||
43 | #include <asm/div64.h> | ||
42 | 44 | ||
43 | MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); | 45 | MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); |
44 | MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); | 46 | MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); |
45 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
46 | 48 | ||
47 | static int debug = 0; | 49 | static int debug = 0; |
48 | module_param(debug, int, 0644); | 50 | module_param(debug, bool, 0644); |
49 | 51 | ||
50 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 52 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
51 | 53 | ||
52 | #define saa7115_dbg(fmt,arg...) \ | ||
53 | do { \ | ||
54 | if (debug) \ | ||
55 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
56 | client->driver->driver.name, \ | ||
57 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
58 | } while (0) | ||
59 | |||
60 | #define saa7115_err(fmt, arg...) do { \ | ||
61 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
62 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
63 | #define saa7115_info(fmt, arg...) do { \ | ||
64 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
65 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
66 | |||
67 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; | 54 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; |
68 | 55 | ||
69 | 56 | ||
@@ -73,12 +60,13 @@ struct saa7115_state { | |||
73 | v4l2_std_id std; | 60 | v4l2_std_id std; |
74 | int input; | 61 | int input; |
75 | int enable; | 62 | int enable; |
63 | int radio; | ||
76 | int bright; | 64 | int bright; |
77 | int contrast; | 65 | int contrast; |
78 | int hue; | 66 | int hue; |
79 | int sat; | 67 | int sat; |
80 | enum v4l2_chip_ident ident; | 68 | enum v4l2_chip_ident ident; |
81 | enum v4l2_audio_clock_freq audclk_freq; | 69 | u32 audclk_freq; |
82 | }; | 70 | }; |
83 | 71 | ||
84 | /* ----------------------------------------------------------------------- */ | 72 | /* ----------------------------------------------------------------------- */ |
@@ -469,80 +457,6 @@ static const unsigned char saa7115_init_misc[] = { | |||
469 | 0x00, 0x00 | 457 | 0x00, 0x00 |
470 | }; | 458 | }; |
471 | 459 | ||
472 | /* ============== SAA7715 AUDIO settings ============= */ | ||
473 | |||
474 | /* 48.0 kHz */ | ||
475 | static const unsigned char saa7115_cfg_48_audio[] = { | ||
476 | 0x34, 0xce, | ||
477 | 0x35, 0xfb, | ||
478 | 0x36, 0x30, | ||
479 | 0x00, 0x00 | ||
480 | }; | ||
481 | |||
482 | /* 44.1 kHz */ | ||
483 | static const unsigned char saa7115_cfg_441_audio[] = { | ||
484 | 0x34, 0xf2, | ||
485 | 0x35, 0x00, | ||
486 | 0x36, 0x2d, | ||
487 | 0x00, 0x00 | ||
488 | }; | ||
489 | |||
490 | /* 32.0 kHz */ | ||
491 | static const unsigned char saa7115_cfg_32_audio[] = { | ||
492 | 0x34, 0xdf, | ||
493 | 0x35, 0xa7, | ||
494 | 0x36, 0x20, | ||
495 | 0x00, 0x00 | ||
496 | }; | ||
497 | |||
498 | /* 48.0 kHz 60hz */ | ||
499 | static const unsigned char saa7115_cfg_60hz_48_audio[] = { | ||
500 | 0x30, 0xcd, | ||
501 | 0x31, 0x20, | ||
502 | 0x32, 0x03, | ||
503 | 0x00, 0x00 | ||
504 | }; | ||
505 | |||
506 | /* 48.0 kHz 50hz */ | ||
507 | static const unsigned char saa7115_cfg_50hz_48_audio[] = { | ||
508 | 0x30, 0x00, | ||
509 | 0x31, 0xc0, | ||
510 | 0x32, 0x03, | ||
511 | 0x00, 0x00 | ||
512 | }; | ||
513 | |||
514 | /* 44.1 kHz 60hz */ | ||
515 | static const unsigned char saa7115_cfg_60hz_441_audio[] = { | ||
516 | 0x30, 0xbc, | ||
517 | 0x31, 0xdf, | ||
518 | 0x32, 0x02, | ||
519 | 0x00, 0x00 | ||
520 | }; | ||
521 | |||
522 | /* 44.1 kHz 50hz */ | ||
523 | static const unsigned char saa7115_cfg_50hz_441_audio[] = { | ||
524 | 0x30, 0x00, | ||
525 | 0x31, 0x72, | ||
526 | 0x32, 0x03, | ||
527 | 0x00, 0x00 | ||
528 | }; | ||
529 | |||
530 | /* 32.0 kHz 60hz */ | ||
531 | static const unsigned char saa7115_cfg_60hz_32_audio[] = { | ||
532 | 0x30, 0xde, | ||
533 | 0x31, 0x15, | ||
534 | 0x32, 0x02, | ||
535 | 0x00, 0x00 | ||
536 | }; | ||
537 | |||
538 | /* 32.0 kHz 50hz */ | ||
539 | static const unsigned char saa7115_cfg_50hz_32_audio[] = { | ||
540 | 0x30, 0x00, | ||
541 | 0x31, 0x80, | ||
542 | 0x32, 0x02, | ||
543 | 0x00, 0x00 | ||
544 | }; | ||
545 | |||
546 | static int saa7115_odd_parity(u8 c) | 460 | static int saa7115_odd_parity(u8 c) |
547 | { | 461 | { |
548 | c ^= (c >> 4); | 462 | c ^= (c >> 4); |
@@ -627,40 +541,38 @@ static int saa7115_decode_wss(u8 * p) | |||
627 | } | 541 | } |
628 | 542 | ||
629 | 543 | ||
630 | static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq) | 544 | static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) |
631 | { | 545 | { |
632 | struct saa7115_state *state = i2c_get_clientdata(client); | 546 | struct saa7115_state *state = i2c_get_clientdata(client); |
547 | u32 acpf; | ||
548 | u32 acni; | ||
549 | u32 hz; | ||
550 | u64 f; | ||
633 | 551 | ||
634 | saa7115_dbg("set audio clock freq: %d\n", freq); | 552 | v4l_dbg(1, client, "set audio clock freq: %d\n", freq); |
635 | switch (freq) { | 553 | |
636 | case V4L2_AUDCLK_32_KHZ: | 554 | /* sanity check */ |
637 | saa7115_writeregs(client, saa7115_cfg_32_audio); | 555 | if (freq < 32000 || freq > 48000) |
638 | if (state->std & V4L2_STD_525_60) { | 556 | return -EINVAL; |
639 | saa7115_writeregs(client, saa7115_cfg_60hz_32_audio); | 557 | |
640 | } else { | 558 | /* hz is the refresh rate times 100 */ |
641 | saa7115_writeregs(client, saa7115_cfg_50hz_32_audio); | 559 | hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; |
642 | } | 560 | /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ |
643 | break; | 561 | acpf = (25600 * freq) / hz; |
644 | case V4L2_AUDCLK_441_KHZ: | 562 | /* acni = (256 * freq * 2^23) / crystal_frequency = |
645 | saa7115_writeregs(client, saa7115_cfg_441_audio); | 563 | (freq * 2^(8+23)) / crystal_frequency = |
646 | if (state->std & V4L2_STD_525_60) { | 564 | (freq << 31) / 32.11 MHz */ |
647 | saa7115_writeregs(client, saa7115_cfg_60hz_441_audio); | 565 | f = freq; |
648 | } else { | 566 | f = f << 31; |
649 | saa7115_writeregs(client, saa7115_cfg_50hz_441_audio); | 567 | do_div(f, 32110000); |
650 | } | 568 | acni = f; |
651 | break; | 569 | |
652 | case V4L2_AUDCLK_48_KHZ: | 570 | saa7115_write(client, 0x30, acpf & 0xff); |
653 | saa7115_writeregs(client, saa7115_cfg_48_audio); | 571 | saa7115_write(client, 0x31, (acpf >> 8) & 0xff); |
654 | if (state->std & V4L2_STD_525_60) { | 572 | saa7115_write(client, 0x32, (acpf >> 16) & 0x03); |
655 | saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); | 573 | saa7115_write(client, 0x34, acni & 0xff); |
656 | } else { | 574 | saa7115_write(client, 0x35, (acni >> 8) & 0xff); |
657 | saa7115_writeregs(client, saa7115_cfg_50hz_48_audio); | 575 | saa7115_write(client, 0x36, (acni >> 16) & 0x3f); |
658 | } | ||
659 | break; | ||
660 | default: | ||
661 | saa7115_dbg("invalid audio setting %d\n", freq); | ||
662 | return -EINVAL; | ||
663 | } | ||
664 | state->audclk_freq = freq; | 576 | state->audclk_freq = freq; |
665 | return 0; | 577 | return 0; |
666 | } | 578 | } |
@@ -672,7 +584,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c | |||
672 | switch (ctrl->id) { | 584 | switch (ctrl->id) { |
673 | case V4L2_CID_BRIGHTNESS: | 585 | case V4L2_CID_BRIGHTNESS: |
674 | if (ctrl->value < 0 || ctrl->value > 255) { | 586 | if (ctrl->value < 0 || ctrl->value > 255) { |
675 | saa7115_err("invalid brightness setting %d\n", ctrl->value); | 587 | v4l_err(client, "invalid brightness setting %d\n", ctrl->value); |
676 | return -ERANGE; | 588 | return -ERANGE; |
677 | } | 589 | } |
678 | 590 | ||
@@ -682,7 +594,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c | |||
682 | 594 | ||
683 | case V4L2_CID_CONTRAST: | 595 | case V4L2_CID_CONTRAST: |
684 | if (ctrl->value < 0 || ctrl->value > 127) { | 596 | if (ctrl->value < 0 || ctrl->value > 127) { |
685 | saa7115_err("invalid contrast setting %d\n", ctrl->value); | 597 | v4l_err(client, "invalid contrast setting %d\n", ctrl->value); |
686 | return -ERANGE; | 598 | return -ERANGE; |
687 | } | 599 | } |
688 | 600 | ||
@@ -692,7 +604,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c | |||
692 | 604 | ||
693 | case V4L2_CID_SATURATION: | 605 | case V4L2_CID_SATURATION: |
694 | if (ctrl->value < 0 || ctrl->value > 127) { | 606 | if (ctrl->value < 0 || ctrl->value > 127) { |
695 | saa7115_err("invalid saturation setting %d\n", ctrl->value); | 607 | v4l_err(client, "invalid saturation setting %d\n", ctrl->value); |
696 | return -ERANGE; | 608 | return -ERANGE; |
697 | } | 609 | } |
698 | 610 | ||
@@ -702,13 +614,16 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c | |||
702 | 614 | ||
703 | case V4L2_CID_HUE: | 615 | case V4L2_CID_HUE: |
704 | if (ctrl->value < -127 || ctrl->value > 127) { | 616 | if (ctrl->value < -127 || ctrl->value > 127) { |
705 | saa7115_err("invalid hue setting %d\n", ctrl->value); | 617 | v4l_err(client, "invalid hue setting %d\n", ctrl->value); |
706 | return -ERANGE; | 618 | return -ERANGE; |
707 | } | 619 | } |
708 | 620 | ||
709 | state->hue = ctrl->value; | 621 | state->hue = ctrl->value; |
710 | saa7115_write(client, 0x0d, state->hue); | 622 | saa7115_write(client, 0x0d, state->hue); |
711 | break; | 623 | break; |
624 | |||
625 | default: | ||
626 | return -EINVAL; | ||
712 | } | 627 | } |
713 | 628 | ||
714 | return 0; | 629 | return 0; |
@@ -743,12 +658,22 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
743 | struct saa7115_state *state = i2c_get_clientdata(client); | 658 | struct saa7115_state *state = i2c_get_clientdata(client); |
744 | int taskb = saa7115_read(client, 0x80) & 0x10; | 659 | int taskb = saa7115_read(client, 0x80) & 0x10; |
745 | 660 | ||
661 | /* Prevent unnecessary standard changes. During a standard | ||
662 | change the I-Port is temporarily disabled. Any devices | ||
663 | reading from that port can get confused. | ||
664 | Note that VIDIOC_S_STD is also used to switch from | ||
665 | radio to TV mode, so if a VIDIOC_S_STD is broadcast to | ||
666 | all I2C devices then you do not want to have an unwanted | ||
667 | side-effect here. */ | ||
668 | if (std == state->std) | ||
669 | return; | ||
670 | |||
746 | // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. | 671 | // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. |
747 | if (std & V4L2_STD_525_60) { | 672 | if (std & V4L2_STD_525_60) { |
748 | saa7115_dbg("decoder set standard 60 Hz\n"); | 673 | v4l_dbg(1, client, "decoder set standard 60 Hz\n"); |
749 | saa7115_writeregs(client, saa7115_cfg_60hz_video); | 674 | saa7115_writeregs(client, saa7115_cfg_60hz_video); |
750 | } else { | 675 | } else { |
751 | saa7115_dbg("decoder set standard 50 Hz\n"); | 676 | v4l_dbg(1, client, "decoder set standard 50 Hz\n"); |
752 | saa7115_writeregs(client, saa7115_cfg_50hz_video); | 677 | saa7115_writeregs(client, saa7115_cfg_50hz_video); |
753 | } | 678 | } |
754 | 679 | ||
@@ -773,24 +698,17 @@ static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client) | |||
773 | static void saa7115_log_status(struct i2c_client *client) | 698 | static void saa7115_log_status(struct i2c_client *client) |
774 | { | 699 | { |
775 | struct saa7115_state *state = i2c_get_clientdata(client); | 700 | struct saa7115_state *state = i2c_get_clientdata(client); |
776 | char *audfreq = "undefined"; | ||
777 | int reg1e, reg1f; | 701 | int reg1e, reg1f; |
778 | int signalOk; | 702 | int signalOk; |
779 | int vcr; | 703 | int vcr; |
780 | 704 | ||
781 | switch (state->audclk_freq) { | 705 | v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); |
782 | case V4L2_AUDCLK_32_KHZ: audfreq = "32 kHz"; break; | ||
783 | case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break; | ||
784 | case V4L2_AUDCLK_48_KHZ: audfreq = "48 kHz"; break; | ||
785 | } | ||
786 | |||
787 | saa7115_info("Audio frequency: %s\n", audfreq); | ||
788 | if (client->name[6] == '4') { | 706 | if (client->name[6] == '4') { |
789 | /* status for the saa7114 */ | 707 | /* status for the saa7114 */ |
790 | reg1f = saa7115_read(client, 0x1f); | 708 | reg1f = saa7115_read(client, 0x1f); |
791 | signalOk = (reg1f & 0xc1) == 0x81; | 709 | signalOk = (reg1f & 0xc1) == 0x81; |
792 | saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad"); | 710 | v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad"); |
793 | saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); | 711 | v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); |
794 | return; | 712 | return; |
795 | } | 713 | } |
796 | 714 | ||
@@ -801,21 +719,26 @@ static void saa7115_log_status(struct i2c_client *client) | |||
801 | signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; | 719 | signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; |
802 | vcr = !(reg1f & 0x10); | 720 | vcr = !(reg1f & 0x10); |
803 | 721 | ||
804 | saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); | 722 | if (state->input >= 6) { |
805 | saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); | 723 | v4l_info(client, "Input: S-Video %d\n", state->input - 6); |
724 | } else { | ||
725 | v4l_info(client, "Input: Composite %d\n", state->input); | ||
726 | } | ||
727 | v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); | ||
728 | v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); | ||
806 | 729 | ||
807 | switch (reg1e & 0x03) { | 730 | switch (reg1e & 0x03) { |
808 | case 1: | 731 | case 1: |
809 | saa7115_info("Detected format: NTSC\n"); | 732 | v4l_info(client, "Detected format: NTSC\n"); |
810 | break; | 733 | break; |
811 | case 2: | 734 | case 2: |
812 | saa7115_info("Detected format: PAL\n"); | 735 | v4l_info(client, "Detected format: PAL\n"); |
813 | break; | 736 | break; |
814 | case 3: | 737 | case 3: |
815 | saa7115_info("Detected format: SECAM\n"); | 738 | v4l_info(client, "Detected format: SECAM\n"); |
816 | break; | 739 | break; |
817 | default: | 740 | default: |
818 | saa7115_info("Detected format: BW/No color\n"); | 741 | v4l_info(client, "Detected format: BW/No color\n"); |
819 | break; | 742 | break; |
820 | } | 743 | } |
821 | } | 744 | } |
@@ -940,7 +863,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt | |||
940 | 863 | ||
941 | pix = &(fmt->fmt.pix); | 864 | pix = &(fmt->fmt.pix); |
942 | 865 | ||
943 | saa7115_dbg("decoder set size\n"); | 866 | v4l_dbg(1, client, "decoder set size\n"); |
944 | 867 | ||
945 | /* FIXME need better bounds checking here */ | 868 | /* FIXME need better bounds checking here */ |
946 | if ((pix->width < 1) || (pix->width > 1440)) | 869 | if ((pix->width < 1) || (pix->width > 1440)) |
@@ -966,7 +889,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt | |||
966 | HPSC = HPSC ? HPSC : 1; | 889 | HPSC = HPSC ? HPSC : 1; |
967 | HFSC = (int)((1024 * 720) / (HPSC * pix->width)); | 890 | HFSC = (int)((1024 * 720) / (HPSC * pix->width)); |
968 | 891 | ||
969 | saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); | 892 | v4l_dbg(1, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); |
970 | /* FIXME hardcodes to "Task B" | 893 | /* FIXME hardcodes to "Task B" |
971 | * write H prescaler integer */ | 894 | * write H prescaler integer */ |
972 | saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f)); | 895 | saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f)); |
@@ -980,10 +903,10 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt | |||
980 | saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff)); | 903 | saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff)); |
981 | } else { | 904 | } else { |
982 | if (is_50hz) { | 905 | if (is_50hz) { |
983 | saa7115_dbg("Setting full 50hz width\n"); | 906 | v4l_dbg(1, client, "Setting full 50hz width\n"); |
984 | saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x); | 907 | saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x); |
985 | } else { | 908 | } else { |
986 | saa7115_dbg("Setting full 60hz width\n"); | 909 | v4l_dbg(1, client, "Setting full 60hz width\n"); |
987 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); | 910 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); |
988 | } | 911 | } |
989 | } | 912 | } |
@@ -992,7 +915,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt | |||
992 | 915 | ||
993 | if (pix->height != Vsrc) { | 916 | if (pix->height != Vsrc) { |
994 | VSCY = (int)((1024 * Vsrc) / pix->height); | 917 | VSCY = (int)((1024 * Vsrc) / pix->height); |
995 | saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); | 918 | v4l_dbg(1, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); |
996 | 919 | ||
997 | /* Correct Contrast and Luminance */ | 920 | /* Correct Contrast and Luminance */ |
998 | saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY)); | 921 | saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY)); |
@@ -1006,10 +929,10 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt | |||
1006 | saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff)); | 929 | saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff)); |
1007 | } else { | 930 | } else { |
1008 | if (is_50hz) { | 931 | if (is_50hz) { |
1009 | saa7115_dbg("Setting full 50Hz height\n"); | 932 | v4l_dbg(1, client, "Setting full 50Hz height\n"); |
1010 | saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y); | 933 | saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y); |
1011 | } else { | 934 | } else { |
1012 | saa7115_dbg("Setting full 60hz height\n"); | 935 | v4l_dbg(1, client, "Setting full 60hz height\n"); |
1013 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); | 936 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); |
1014 | } | 937 | } |
1015 | } | 938 | } |
@@ -1089,6 +1012,48 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, | |||
1089 | 1012 | ||
1090 | /* ============ SAA7115 AUDIO settings (end) ============= */ | 1013 | /* ============ SAA7115 AUDIO settings (end) ============= */ |
1091 | 1014 | ||
1015 | static struct v4l2_queryctrl saa7115_qctrl[] = { | ||
1016 | { | ||
1017 | .id = V4L2_CID_BRIGHTNESS, | ||
1018 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1019 | .name = "Brightness", | ||
1020 | .minimum = 0, | ||
1021 | .maximum = 255, | ||
1022 | .step = 1, | ||
1023 | .default_value = 128, | ||
1024 | .flags = 0, | ||
1025 | }, { | ||
1026 | .id = V4L2_CID_CONTRAST, | ||
1027 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1028 | .name = "Contrast", | ||
1029 | .minimum = 0, | ||
1030 | .maximum = 255, | ||
1031 | .step = 1, | ||
1032 | .default_value = 64, | ||
1033 | .flags = 0, | ||
1034 | }, { | ||
1035 | .id = V4L2_CID_SATURATION, | ||
1036 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1037 | .name = "Saturation", | ||
1038 | .minimum = 0, | ||
1039 | .maximum = 255, | ||
1040 | .step = 1, | ||
1041 | .default_value = 64, | ||
1042 | .flags = 0, | ||
1043 | }, { | ||
1044 | .id = V4L2_CID_HUE, | ||
1045 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1046 | .name = "Hue", | ||
1047 | .minimum = -128, | ||
1048 | .maximum = 127, | ||
1049 | .step = 1, | ||
1050 | .default_value = 0, | ||
1051 | .flags = 0, | ||
1052 | }, | ||
1053 | }; | ||
1054 | |||
1055 | /* ----------------------------------------------------------------------- */ | ||
1056 | |||
1092 | static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) | 1057 | static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) |
1093 | { | 1058 | { |
1094 | struct saa7115_state *state = i2c_get_clientdata(client); | 1059 | struct saa7115_state *state = i2c_get_clientdata(client); |
@@ -1103,16 +1068,18 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1103 | return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); | 1068 | return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); |
1104 | 1069 | ||
1105 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 1070 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
1106 | return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg); | 1071 | return saa7115_set_audio_clock_freq(client, *(u32 *)arg); |
1107 | 1072 | ||
1108 | case VIDIOC_G_TUNER: | 1073 | case VIDIOC_G_TUNER: |
1109 | { | 1074 | { |
1110 | struct v4l2_tuner *vt = arg; | 1075 | struct v4l2_tuner *vt = arg; |
1111 | int status; | 1076 | int status; |
1112 | 1077 | ||
1078 | if (state->radio) | ||
1079 | break; | ||
1113 | status = saa7115_read(client, 0x1f); | 1080 | status = saa7115_read(client, 0x1f); |
1114 | 1081 | ||
1115 | saa7115_dbg("status: 0x%02x\n", status); | 1082 | v4l_dbg(1, client, "status: 0x%02x\n", status); |
1116 | vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; | 1083 | vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; |
1117 | break; | 1084 | break; |
1118 | } | 1085 | } |
@@ -1127,20 +1094,38 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1127 | case VIDIOC_S_CTRL: | 1094 | case VIDIOC_S_CTRL: |
1128 | return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg); | 1095 | return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg); |
1129 | 1096 | ||
1097 | case VIDIOC_QUERYCTRL: | ||
1098 | { | ||
1099 | struct v4l2_queryctrl *qc = arg; | ||
1100 | int i; | ||
1101 | |||
1102 | for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++) | ||
1103 | if (qc->id && qc->id == saa7115_qctrl[i].id) { | ||
1104 | memcpy(qc, &saa7115_qctrl[i], sizeof(*qc)); | ||
1105 | return 0; | ||
1106 | } | ||
1107 | return -EINVAL; | ||
1108 | } | ||
1109 | |||
1130 | case VIDIOC_G_STD: | 1110 | case VIDIOC_G_STD: |
1131 | *(v4l2_std_id *)arg = saa7115_get_v4lstd(client); | 1111 | *(v4l2_std_id *)arg = saa7115_get_v4lstd(client); |
1132 | break; | 1112 | break; |
1133 | 1113 | ||
1134 | case VIDIOC_S_STD: | 1114 | case VIDIOC_S_STD: |
1115 | state->radio = 0; | ||
1135 | saa7115_set_v4lstd(client, *(v4l2_std_id *)arg); | 1116 | saa7115_set_v4lstd(client, *(v4l2_std_id *)arg); |
1136 | break; | 1117 | break; |
1137 | 1118 | ||
1119 | case AUDC_SET_RADIO: | ||
1120 | state->radio = 1; | ||
1121 | break; | ||
1122 | |||
1138 | case VIDIOC_G_INPUT: | 1123 | case VIDIOC_G_INPUT: |
1139 | *(int *)arg = state->input; | 1124 | *(int *)arg = state->input; |
1140 | break; | 1125 | break; |
1141 | 1126 | ||
1142 | case VIDIOC_S_INPUT: | 1127 | case VIDIOC_S_INPUT: |
1143 | saa7115_dbg("decoder set input %d\n", *iarg); | 1128 | v4l_dbg(1, client, "decoder set input %d\n", *iarg); |
1144 | /* inputs from 0-9 are available */ | 1129 | /* inputs from 0-9 are available */ |
1145 | if (*iarg < 0 || *iarg > 9) { | 1130 | if (*iarg < 0 || *iarg > 9) { |
1146 | return -EINVAL; | 1131 | return -EINVAL; |
@@ -1148,7 +1133,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1148 | 1133 | ||
1149 | if (state->input == *iarg) | 1134 | if (state->input == *iarg) |
1150 | break; | 1135 | break; |
1151 | saa7115_dbg("now setting %s input\n", | 1136 | v4l_dbg(1, client, "now setting %s input\n", |
1152 | *iarg >= 6 ? "S-Video" : "Composite"); | 1137 | *iarg >= 6 ? "S-Video" : "Composite"); |
1153 | state->input = *iarg; | 1138 | state->input = *iarg; |
1154 | 1139 | ||
@@ -1165,7 +1150,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1165 | 1150 | ||
1166 | case VIDIOC_STREAMON: | 1151 | case VIDIOC_STREAMON: |
1167 | case VIDIOC_STREAMOFF: | 1152 | case VIDIOC_STREAMOFF: |
1168 | saa7115_dbg("%s output\n", | 1153 | v4l_dbg(1, client, "%s output\n", |
1169 | (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); | 1154 | (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); |
1170 | 1155 | ||
1171 | if (state->enable != (cmd == VIDIOC_STREAMON)) { | 1156 | if (state->enable != (cmd == VIDIOC_STREAMON)) { |
@@ -1179,7 +1164,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1179 | break; | 1164 | break; |
1180 | 1165 | ||
1181 | case VIDIOC_INT_RESET: | 1166 | case VIDIOC_INT_RESET: |
1182 | saa7115_dbg("decoder RESET\n"); | 1167 | v4l_dbg(1, client, "decoder RESET\n"); |
1183 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); | 1168 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); |
1184 | break; | 1169 | break; |
1185 | 1170 | ||
@@ -1273,19 +1258,19 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1273 | client->driver = &i2c_driver_saa7115; | 1258 | client->driver = &i2c_driver_saa7115; |
1274 | snprintf(client->name, sizeof(client->name) - 1, "saa7115"); | 1259 | snprintf(client->name, sizeof(client->name) - 1, "saa7115"); |
1275 | 1260 | ||
1276 | saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1); | 1261 | v4l_dbg(1, client, "detecting saa7115 client on address 0x%x\n", address << 1); |
1277 | 1262 | ||
1278 | saa7115_write(client, 0, 5); | 1263 | saa7115_write(client, 0, 5); |
1279 | chip_id = saa7115_read(client, 0) & 0x0f; | 1264 | chip_id = saa7115_read(client, 0) & 0x0f; |
1280 | if (chip_id != 4 && chip_id != 5) { | 1265 | if (chip_id != 4 && chip_id != 5) { |
1281 | saa7115_dbg("saa7115 not found\n"); | 1266 | v4l_dbg(1, client, "saa7115 not found\n"); |
1282 | kfree(client); | 1267 | kfree(client); |
1283 | return 0; | 1268 | return 0; |
1284 | } | 1269 | } |
1285 | if (chip_id == 4) { | 1270 | if (chip_id == 4) { |
1286 | snprintf(client->name, sizeof(client->name) - 1, "saa7114"); | 1271 | snprintf(client->name, sizeof(client->name) - 1, "saa7114"); |
1287 | } | 1272 | } |
1288 | saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); | 1273 | v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); |
1289 | 1274 | ||
1290 | state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL); | 1275 | state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL); |
1291 | i2c_set_clientdata(client, state); | 1276 | i2c_set_clientdata(client, state); |
@@ -1297,14 +1282,15 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1297 | state->std = V4L2_STD_NTSC; | 1282 | state->std = V4L2_STD_NTSC; |
1298 | state->input = -1; | 1283 | state->input = -1; |
1299 | state->enable = 1; | 1284 | state->enable = 1; |
1285 | state->radio = 0; | ||
1300 | state->bright = 128; | 1286 | state->bright = 128; |
1301 | state->contrast = 64; | 1287 | state->contrast = 64; |
1302 | state->hue = 0; | 1288 | state->hue = 0; |
1303 | state->sat = 64; | 1289 | state->sat = 64; |
1304 | state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; | 1290 | state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; |
1305 | state->audclk_freq = V4L2_AUDCLK_48_KHZ; | 1291 | state->audclk_freq = 48000; |
1306 | 1292 | ||
1307 | saa7115_dbg("writing init values\n"); | 1293 | v4l_dbg(1, client, "writing init values\n"); |
1308 | 1294 | ||
1309 | /* init to 60hz/48khz */ | 1295 | /* init to 60hz/48khz */ |
1310 | saa7115_writeregs(client, saa7115_init_auto_input); | 1296 | saa7115_writeregs(client, saa7115_init_auto_input); |
@@ -1312,13 +1298,12 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1312 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); | 1298 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); |
1313 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); | 1299 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); |
1314 | saa7115_writeregs(client, saa7115_cfg_60hz_video); | 1300 | saa7115_writeregs(client, saa7115_cfg_60hz_video); |
1315 | saa7115_writeregs(client, saa7115_cfg_48_audio); | 1301 | saa7115_set_audio_clock_freq(client, state->audclk_freq); |
1316 | saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); | ||
1317 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); | 1302 | saa7115_writeregs(client, saa7115_cfg_reset_scaler); |
1318 | 1303 | ||
1319 | i2c_attach_client(client); | 1304 | i2c_attach_client(client); |
1320 | 1305 | ||
1321 | saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n", | 1306 | v4l_dbg(1, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", |
1322 | saa7115_read(client, 0x1e), saa7115_read(client, 0x1f)); | 1307 | saa7115_read(client, 0x1e), saa7115_read(client, 0x1f)); |
1323 | 1308 | ||
1324 | return 0; | 1309 | return 0; |
@@ -1326,11 +1311,7 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1326 | 1311 | ||
1327 | static int saa7115_probe(struct i2c_adapter *adapter) | 1312 | static int saa7115_probe(struct i2c_adapter *adapter) |
1328 | { | 1313 | { |
1329 | #ifdef I2C_CLASS_TV_ANALOG | ||
1330 | if (adapter->class & I2C_CLASS_TV_ANALOG) | 1314 | if (adapter->class & I2C_CLASS_TV_ANALOG) |
1331 | #else | ||
1332 | if (adapter->id == I2C_HW_B_BT848) | ||
1333 | #endif | ||
1334 | return i2c_probe(adapter, &addr_data, &saa7115_attach); | 1315 | return i2c_probe(adapter, &addr_data, &saa7115_attach); |
1335 | return 0; | 1316 | return 0; |
1336 | } | 1317 | } |
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 8008537391b5..f39a7be08588 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c | |||
@@ -567,9 +567,7 @@ static struct i2c_driver i2c_driver_saa711x = { | |||
567 | .driver = { | 567 | .driver = { |
568 | .name = "saa711x", | 568 | .name = "saa711x", |
569 | }, | 569 | }, |
570 | |||
571 | .id = I2C_DRIVERID_SAA711X, | 570 | .id = I2C_DRIVERID_SAA711X, |
572 | |||
573 | .attach_adapter = saa711x_attach_adapter, | 571 | .attach_adapter = saa711x_attach_adapter, |
574 | .detach_client = saa711x_detach_client, | 572 | .detach_client = saa711x_detach_client, |
575 | .command = saa711x_command, | 573 | .command = saa711x_command, |
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index bca6ed0e2752..2009c1bc4720 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
@@ -66,30 +66,6 @@ module_param(test_image, int, 0644); | |||
66 | MODULE_PARM_DESC(debug, "debug level (0-2)"); | 66 | MODULE_PARM_DESC(debug, "debug level (0-2)"); |
67 | MODULE_PARM_DESC(test_image, "test_image (0-1)"); | 67 | MODULE_PARM_DESC(test_image, "test_image (0-1)"); |
68 | 68 | ||
69 | #define saa7127_dbg(fmt, arg...) \ | ||
70 | do { \ | ||
71 | if (debug >= 1) \ | ||
72 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
73 | client->driver->driver.name, \ | ||
74 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
75 | } while (0) | ||
76 | |||
77 | /* High volume debug. Use with care. */ | ||
78 | #define saa7127_dbg_highvol(fmt, arg...) \ | ||
79 | do { \ | ||
80 | if (debug == 2) \ | ||
81 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ | ||
82 | client->driver->driver.name, \ | ||
83 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
84 | } while (0) | ||
85 | |||
86 | #define saa7127_err(fmt, arg...) do { \ | ||
87 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
88 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
89 | #define saa7127_info(fmt, arg...) do { \ | ||
90 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
91 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
92 | |||
93 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 69 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
94 | 70 | ||
95 | 71 | ||
@@ -336,7 +312,7 @@ static int saa7127_write(struct i2c_client *client, u8 reg, u8 val) | |||
336 | if (i2c_smbus_write_byte_data(client, reg, val) == 0) | 312 | if (i2c_smbus_write_byte_data(client, reg, val) == 0) |
337 | return 0; | 313 | return 0; |
338 | } | 314 | } |
339 | saa7127_err("I2C Write Problem\n"); | 315 | v4l_err(client, "I2C Write Problem\n"); |
340 | return -1; | 316 | return -1; |
341 | } | 317 | } |
342 | 318 | ||
@@ -362,7 +338,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
362 | if (enable && (data->field != 0 || data->line != 16)) | 338 | if (enable && (data->field != 0 || data->line != 16)) |
363 | return -EINVAL; | 339 | return -EINVAL; |
364 | if (state->vps_enable != enable) { | 340 | if (state->vps_enable != enable) { |
365 | saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off"); | 341 | v4l_dbg(1, client, "Turn VPS Signal %s\n", enable ? "on" : "off"); |
366 | saa7127_write(client, 0x54, enable << 7); | 342 | saa7127_write(client, 0x54, enable << 7); |
367 | state->vps_enable = enable; | 343 | state->vps_enable = enable; |
368 | } | 344 | } |
@@ -374,7 +350,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
374 | state->vps_data[2] = data->data[11]; | 350 | state->vps_data[2] = data->data[11]; |
375 | state->vps_data[3] = data->data[12]; | 351 | state->vps_data[3] = data->data[12]; |
376 | state->vps_data[4] = data->data[13]; | 352 | state->vps_data[4] = data->data[13]; |
377 | saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n", | 353 | v4l_dbg(1, client, "Set VPS data %02x %02x %02x %02x %02x\n", |
378 | state->vps_data[0], state->vps_data[1], | 354 | state->vps_data[0], state->vps_data[1], |
379 | state->vps_data[2], state->vps_data[3], | 355 | state->vps_data[2], state->vps_data[3], |
380 | state->vps_data[4]); | 356 | state->vps_data[4]); |
@@ -397,7 +373,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data | |||
397 | if (enable && (data->field != 0 || data->line != 21)) | 373 | if (enable && (data->field != 0 || data->line != 21)) |
398 | return -EINVAL; | 374 | return -EINVAL; |
399 | if (state->cc_enable != enable) { | 375 | if (state->cc_enable != enable) { |
400 | saa7127_dbg("Turn CC %s\n", enable ? "on" : "off"); | 376 | v4l_dbg(1, client, "Turn CC %s\n", enable ? "on" : "off"); |
401 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, | 377 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, |
402 | (state->xds_enable << 7) | (enable << 6) | 0x11); | 378 | (state->xds_enable << 7) | (enable << 6) | 0x11); |
403 | state->cc_enable = enable; | 379 | state->cc_enable = enable; |
@@ -405,7 +381,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data | |||
405 | if (!enable) | 381 | if (!enable) |
406 | return 0; | 382 | return 0; |
407 | 383 | ||
408 | saa7127_dbg_highvol("CC data: %04x\n", cc); | 384 | v4l_dbg(2, client, "CC data: %04x\n", cc); |
409 | saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff); | 385 | saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff); |
410 | saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8); | 386 | saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8); |
411 | state->cc_data = cc; | 387 | state->cc_data = cc; |
@@ -423,7 +399,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
423 | if (enable && (data->field != 1 || data->line != 21)) | 399 | if (enable && (data->field != 1 || data->line != 21)) |
424 | return -EINVAL; | 400 | return -EINVAL; |
425 | if (state->xds_enable != enable) { | 401 | if (state->xds_enable != enable) { |
426 | saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off"); | 402 | v4l_dbg(1, client, "Turn XDS %s\n", enable ? "on" : "off"); |
427 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, | 403 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, |
428 | (enable << 7) | (state->cc_enable << 6) | 0x11); | 404 | (enable << 7) | (state->cc_enable << 6) | 0x11); |
429 | state->xds_enable = enable; | 405 | state->xds_enable = enable; |
@@ -431,7 +407,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
431 | if (!enable) | 407 | if (!enable) |
432 | return 0; | 408 | return 0; |
433 | 409 | ||
434 | saa7127_dbg_highvol("XDS data: %04x\n", xds); | 410 | v4l_dbg(2, client, "XDS data: %04x\n", xds); |
435 | saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff); | 411 | saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff); |
436 | saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8); | 412 | saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8); |
437 | state->xds_data = xds; | 413 | state->xds_data = xds; |
@@ -448,7 +424,7 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
448 | if (enable && (data->field != 0 || data->line != 23)) | 424 | if (enable && (data->field != 0 || data->line != 23)) |
449 | return -EINVAL; | 425 | return -EINVAL; |
450 | if (state->wss_enable != enable) { | 426 | if (state->wss_enable != enable) { |
451 | saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off"); | 427 | v4l_dbg(1, client, "Turn WSS %s\n", enable ? "on" : "off"); |
452 | saa7127_write(client, 0x27, enable << 7); | 428 | saa7127_write(client, 0x27, enable << 7); |
453 | state->wss_enable = enable; | 429 | state->wss_enable = enable; |
454 | } | 430 | } |
@@ -457,7 +433,7 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
457 | 433 | ||
458 | saa7127_write(client, 0x26, data->data[0]); | 434 | saa7127_write(client, 0x26, data->data[0]); |
459 | saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f)); | 435 | saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f)); |
460 | saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); | 436 | v4l_dbg(1, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); |
461 | state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0]; | 437 | state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0]; |
462 | return 0; | 438 | return 0; |
463 | } | 439 | } |
@@ -469,11 +445,11 @@ static int saa7127_set_video_enable(struct i2c_client *client, int enable) | |||
469 | struct saa7127_state *state = i2c_get_clientdata(client); | 445 | struct saa7127_state *state = i2c_get_clientdata(client); |
470 | 446 | ||
471 | if (enable) { | 447 | if (enable) { |
472 | saa7127_dbg("Enable Video Output\n"); | 448 | v4l_dbg(1, client, "Enable Video Output\n"); |
473 | saa7127_write(client, 0x2d, state->reg_2d); | 449 | saa7127_write(client, 0x2d, state->reg_2d); |
474 | saa7127_write(client, 0x61, state->reg_61); | 450 | saa7127_write(client, 0x61, state->reg_61); |
475 | } else { | 451 | } else { |
476 | saa7127_dbg("Disable Video Output\n"); | 452 | v4l_dbg(1, client, "Disable Video Output\n"); |
477 | saa7127_write(client, 0x2d, (state->reg_2d & 0xf0)); | 453 | saa7127_write(client, 0x2d, (state->reg_2d & 0xf0)); |
478 | saa7127_write(client, 0x61, (state->reg_61 | 0xc0)); | 454 | saa7127_write(client, 0x61, (state->reg_61 | 0xc0)); |
479 | } | 455 | } |
@@ -489,11 +465,11 @@ static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std) | |||
489 | const struct i2c_reg_value *inittab; | 465 | const struct i2c_reg_value *inittab; |
490 | 466 | ||
491 | if (std & V4L2_STD_525_60) { | 467 | if (std & V4L2_STD_525_60) { |
492 | saa7127_dbg("Selecting 60 Hz video Standard\n"); | 468 | v4l_dbg(1, client, "Selecting 60 Hz video Standard\n"); |
493 | inittab = saa7127_init_config_60hz; | 469 | inittab = saa7127_init_config_60hz; |
494 | state->reg_61 = SAA7127_60HZ_DAC_CONTROL; | 470 | state->reg_61 = SAA7127_60HZ_DAC_CONTROL; |
495 | } else { | 471 | } else { |
496 | saa7127_dbg("Selecting 50 Hz video Standard\n"); | 472 | v4l_dbg(1, client, "Selecting 50 Hz video Standard\n"); |
497 | inittab = saa7127_init_config_50hz; | 473 | inittab = saa7127_init_config_50hz; |
498 | state->reg_61 = SAA7127_50HZ_DAC_CONTROL; | 474 | state->reg_61 = SAA7127_50HZ_DAC_CONTROL; |
499 | } | 475 | } |
@@ -544,7 +520,7 @@ static int saa7127_set_output_type(struct i2c_client *client, int output) | |||
544 | default: | 520 | default: |
545 | return -EINVAL; | 521 | return -EINVAL; |
546 | } | 522 | } |
547 | saa7127_dbg("Selecting %s output type\n", output_strs[output]); | 523 | v4l_dbg(1, client, "Selecting %s output type\n", output_strs[output]); |
548 | 524 | ||
549 | /* Configure Encoder */ | 525 | /* Configure Encoder */ |
550 | saa7127_write(client, 0x2d, state->reg_2d); | 526 | saa7127_write(client, 0x2d, state->reg_2d); |
@@ -561,12 +537,12 @@ static int saa7127_set_input_type(struct i2c_client *client, int input) | |||
561 | 537 | ||
562 | switch (input) { | 538 | switch (input) { |
563 | case SAA7127_INPUT_TYPE_NORMAL: /* avia */ | 539 | case SAA7127_INPUT_TYPE_NORMAL: /* avia */ |
564 | saa7127_dbg("Selecting Normal Encoder Input\n"); | 540 | v4l_dbg(1, client, "Selecting Normal Encoder Input\n"); |
565 | state->reg_3a_cb = 0; | 541 | state->reg_3a_cb = 0; |
566 | break; | 542 | break; |
567 | 543 | ||
568 | case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */ | 544 | case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */ |
569 | saa7127_dbg("Selecting Color Bar generator\n"); | 545 | v4l_dbg(1, client, "Selecting Color Bar generator\n"); |
570 | state->reg_3a_cb = 0x80; | 546 | state->reg_3a_cb = 0x80; |
571 | break; | 547 | break; |
572 | 548 | ||
@@ -633,14 +609,14 @@ static int saa7127_command(struct i2c_client *client, | |||
633 | break; | 609 | break; |
634 | 610 | ||
635 | case VIDIOC_LOG_STATUS: | 611 | case VIDIOC_LOG_STATUS: |
636 | saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); | 612 | v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); |
637 | saa7127_info("Input: %s\n", state->input_type ? "color bars" : "normal"); | 613 | v4l_info(client, "Input: %s\n", state->input_type ? "color bars" : "normal"); |
638 | saa7127_info("Output: %s\n", state->video_enable ? | 614 | v4l_info(client, "Output: %s\n", state->video_enable ? |
639 | output_strs[state->output_type] : "disabled"); | 615 | output_strs[state->output_type] : "disabled"); |
640 | saa7127_info("WSS: %s\n", state->wss_enable ? | 616 | v4l_info(client, "WSS: %s\n", state->wss_enable ? |
641 | wss_strs[state->wss_mode] : "disabled"); | 617 | wss_strs[state->wss_mode] : "disabled"); |
642 | saa7127_info("VPS: %s\n", state->vps_enable ? "enabled" : "disabled"); | 618 | v4l_info(client, "VPS: %s\n", state->vps_enable ? "enabled" : "disabled"); |
643 | saa7127_info("CC: %s\n", state->cc_enable ? "enabled" : "disabled"); | 619 | v4l_info(client, "CC: %s\n", state->cc_enable ? "enabled" : "disabled"); |
644 | break; | 620 | break; |
645 | 621 | ||
646 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 622 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
@@ -723,7 +699,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | |||
723 | client->driver = &i2c_driver_saa7127; | 699 | client->driver = &i2c_driver_saa7127; |
724 | snprintf(client->name, sizeof(client->name) - 1, "saa7127"); | 700 | snprintf(client->name, sizeof(client->name) - 1, "saa7127"); |
725 | 701 | ||
726 | saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1); | 702 | v4l_dbg(1, client, "detecting saa7127 client on address 0x%x\n", address << 1); |
727 | 703 | ||
728 | /* First test register 0: Bits 5-7 are a version ID (should be 0), | 704 | /* First test register 0: Bits 5-7 are a version ID (should be 0), |
729 | and bit 2 should also be 0. | 705 | and bit 2 should also be 0. |
@@ -732,7 +708,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | |||
732 | 0x1d after a reset and not expected to ever change. */ | 708 | 0x1d after a reset and not expected to ever change. */ |
733 | if ((saa7127_read(client, 0) & 0xe4) != 0 || | 709 | if ((saa7127_read(client, 0) & 0xe4) != 0 || |
734 | (saa7127_read(client, 0x29) & 0x3f) != 0x1d) { | 710 | (saa7127_read(client, 0x29) & 0x3f) != 0x1d) { |
735 | saa7127_dbg("saa7127 not found\n"); | 711 | v4l_dbg(1, client, "saa7127 not found\n"); |
736 | kfree(client); | 712 | kfree(client); |
737 | return 0; | 713 | return 0; |
738 | } | 714 | } |
@@ -748,7 +724,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | |||
748 | 724 | ||
749 | /* Configure Encoder */ | 725 | /* Configure Encoder */ |
750 | 726 | ||
751 | saa7127_dbg("Configuring encoder\n"); | 727 | v4l_dbg(1, client, "Configuring encoder\n"); |
752 | saa7127_write_inittab(client, saa7127_init_config_common); | 728 | saa7127_write_inittab(client, saa7127_init_config_common); |
753 | saa7127_set_std(client, V4L2_STD_NTSC); | 729 | saa7127_set_std(client, V4L2_STD_NTSC); |
754 | saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); | 730 | saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); |
@@ -769,12 +745,12 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | |||
769 | read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); | 745 | read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); |
770 | saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); | 746 | saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); |
771 | if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { | 747 | if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { |
772 | saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name); | 748 | v4l_info(client, "saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name); |
773 | saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result); | 749 | saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result); |
774 | saa7127_write_inittab(client, saa7129_init_config_extra); | 750 | saa7127_write_inittab(client, saa7129_init_config_extra); |
775 | state->ident = V4L2_IDENT_SAA7129; | 751 | state->ident = V4L2_IDENT_SAA7129; |
776 | } else { | 752 | } else { |
777 | saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name); | 753 | v4l_info(client, "saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name); |
778 | state->ident = V4L2_IDENT_SAA7127; | 754 | state->ident = V4L2_IDENT_SAA7127; |
779 | } | 755 | } |
780 | 756 | ||
@@ -787,11 +763,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | |||
787 | 763 | ||
788 | static int saa7127_probe(struct i2c_adapter *adapter) | 764 | static int saa7127_probe(struct i2c_adapter *adapter) |
789 | { | 765 | { |
790 | #ifdef I2C_CLASS_TV_ANALOG | ||
791 | if (adapter->class & I2C_CLASS_TV_ANALOG) | 766 | if (adapter->class & I2C_CLASS_TV_ANALOG) |
792 | #else | ||
793 | if (adapter->id == I2C_HW_B_BT848) | ||
794 | #endif | ||
795 | return i2c_probe(adapter, &addr_data, saa7127_attach); | 767 | return i2c_probe(adapter, &addr_data, saa7127_attach); |
796 | return 0; | 768 | return 0; |
797 | } | 769 | } |
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 4615a982ac64..ad73c4a60f2b 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -9,7 +9,8 @@ | |||
9 | #include <linux/poll.h> | 9 | #include <linux/poll.h> |
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/videodev.h> | 12 | #include <linux/videodev2.h> |
13 | #include <media/v4l2-common.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
15 | 16 | ||
@@ -509,7 +510,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | |||
509 | { | 510 | { |
510 | struct saa6752hs_state *h; | 511 | struct saa6752hs_state *h; |
511 | 512 | ||
512 | printk("saa6752hs: chip found @ 0x%x\n", addr<<1); | ||
513 | 513 | ||
514 | if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) | 514 | if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) |
515 | return -ENOMEM; | 515 | return -ENOMEM; |
@@ -525,6 +525,8 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | |||
525 | i2c_set_clientdata(&h->client, h); | 525 | i2c_set_clientdata(&h->client, h); |
526 | i2c_attach_client(&h->client); | 526 | i2c_attach_client(&h->client); |
527 | 527 | ||
528 | v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); | ||
529 | |||
528 | return 0; | 530 | return 0; |
529 | } | 531 | } |
530 | 532 | ||
@@ -598,7 +600,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
598 | 600 | ||
599 | static struct i2c_driver driver = { | 601 | static struct i2c_driver driver = { |
600 | .driver = { | 602 | .driver = { |
601 | .name = "i2c saa6752hs MPEG encoder", | 603 | .name = "saa6752hs", |
602 | }, | 604 | }, |
603 | .id = I2C_DRIVERID_SAA6752HS, | 605 | .id = I2C_DRIVERID_SAA6752HS, |
604 | .attach_adapter = saa6752hs_probe, | 606 | .attach_adapter = saa6752hs_probe, |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index ade05f75fdb0..a7a6ab9298a9 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -20,13 +20,13 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <sound/driver.h> | ||
24 | #include <linux/init.h> | 23 | #include <linux/init.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
26 | #include <linux/time.h> | 25 | #include <linux/time.h> |
27 | #include <linux/wait.h> | 26 | #include <linux/wait.h> |
28 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <sound/driver.h> | ||
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/control.h> | 31 | #include <sound/control.h> |
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 672fb205959f..77e5be98e4c6 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "saa7134-reg.h" | 26 | #include "saa7134-reg.h" |
27 | #include "saa7134.h" | 27 | #include "saa7134.h" |
28 | #include <media/v4l2-common.h> | ||
28 | 29 | ||
29 | /* commly used strings */ | 30 | /* commly used strings */ |
30 | static char name_mute[] = "mute"; | 31 | static char name_mute[] = "mute"; |
@@ -2555,6 +2556,69 @@ struct saa7134_board saa7134_boards[] = { | |||
2555 | .amux = LINE1, | 2556 | .amux = LINE1, |
2556 | }, | 2557 | }, |
2557 | }, | 2558 | }, |
2559 | [SAA7134_BOARD_CINERGY250PCI] = { | ||
2560 | /* remote-control does not work. The signal about a | ||
2561 | key press comes in via gpio, but the key code | ||
2562 | doesn't. Neither does it have an i2c remote control | ||
2563 | interface. */ | ||
2564 | .name = "Terratec Cinergy 250 PCI TV", | ||
2565 | .audio_clock = 0x00187de7, | ||
2566 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2567 | .radio_type = UNSET, | ||
2568 | .tuner_addr = ADDR_UNSET, | ||
2569 | .radio_addr = ADDR_UNSET, | ||
2570 | .gpiomask = 0x80200000, | ||
2571 | .inputs = {{ | ||
2572 | .name = name_tv, | ||
2573 | .vmux = 1, | ||
2574 | .amux = TV, | ||
2575 | .tv = 1, | ||
2576 | },{ | ||
2577 | .name = name_svideo, /* NOT tested */ | ||
2578 | .vmux = 8, | ||
2579 | .amux = LINE1, | ||
2580 | }}, | ||
2581 | .radio = { | ||
2582 | .name = name_radio, | ||
2583 | .amux = LINE1, | ||
2584 | .gpio = 0x0200000, | ||
2585 | }, | ||
2586 | }, | ||
2587 | [SAA7134_BOARD_FLYDVB_TRIO] = { | ||
2588 | /* LifeView LR319 FlyDVB Trio */ | ||
2589 | /* Peter Missel <peter.missel@onlinehome.de> */ | ||
2590 | .name = "LifeView FlyDVB Trio", | ||
2591 | .audio_clock = 0x00200000, | ||
2592 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2593 | .radio_type = UNSET, | ||
2594 | .tuner_addr = ADDR_UNSET, | ||
2595 | .radio_addr = ADDR_UNSET, | ||
2596 | .gpiomask = 0x00200000, | ||
2597 | .inputs = {{ | ||
2598 | .name = name_tv, /* Analog broadcast/cable TV */ | ||
2599 | .vmux = 1, | ||
2600 | .amux = TV, | ||
2601 | .gpio = 0x200000, /* GPIO21=High for TV input */ | ||
2602 | .tv = 1, | ||
2603 | },{ | ||
2604 | .name = name_svideo, /* S-Video signal on S-Video input */ | ||
2605 | .vmux = 8, | ||
2606 | .amux = LINE2, | ||
2607 | },{ | ||
2608 | .name = name_comp1, /* Composite signal on S-Video input */ | ||
2609 | .vmux = 0, | ||
2610 | .amux = LINE2, | ||
2611 | },{ | ||
2612 | .name = name_comp2, /* Composite input */ | ||
2613 | .vmux = 3, | ||
2614 | .amux = LINE2, | ||
2615 | }}, | ||
2616 | .radio = { | ||
2617 | .name = name_radio, | ||
2618 | .amux = TV, | ||
2619 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ | ||
2620 | }, | ||
2621 | }, | ||
2558 | }; | 2622 | }; |
2559 | 2623 | ||
2560 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 2624 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -2895,6 +2959,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2895 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2959 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2896 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2960 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
2897 | .subvendor = 0x1421, | 2961 | .subvendor = 0x1421, |
2962 | .subdevice = 0x0351, /* PCI version, new revision */ | ||
2963 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | ||
2964 | },{ | ||
2965 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2966 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2967 | .subvendor = 0x1421, | ||
2898 | .subdevice = 0x0370, /* cardbus version */ | 2968 | .subdevice = 0x0370, /* cardbus version */ |
2899 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | 2969 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, |
2900 | },{ | 2970 | },{ |
@@ -3002,6 +3072,18 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
3002 | .subdevice = 0x6231, | 3072 | .subdevice = 0x6231, |
3003 | .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, | 3073 | .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, |
3004 | },{ | 3074 | },{ |
3075 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
3076 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
3077 | .subvendor = 0x153b, | ||
3078 | .subdevice = 0x1160, | ||
3079 | .driver_data = SAA7134_BOARD_CINERGY250PCI, | ||
3080 | },{ | ||
3081 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
3082 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA 7131E */ | ||
3083 | .subvendor = 0x5168, | ||
3084 | .subdevice = 0x0319, | ||
3085 | .driver_data = SAA7134_BOARD_FLYDVB_TRIO, | ||
3086 | },{ | ||
3005 | /* --- boards without eeprom + subsystem ID --- */ | 3087 | /* --- boards without eeprom + subsystem ID --- */ |
3006 | .vendor = PCI_VENDOR_ID_PHILIPS, | 3088 | .vendor = PCI_VENDOR_ID_PHILIPS, |
3007 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 3089 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -3090,6 +3172,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3090 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 3172 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
3091 | /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ | 3173 | /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ |
3092 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 3174 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
3175 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: | ||
3093 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: | 3176 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: |
3094 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 3177 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
3095 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 3178 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 23d8747338ed..accbc32725cf 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -95,77 +95,6 @@ int (*dmasound_exit)(struct saa7134_dev *dev); | |||
95 | #define dprintk(fmt, arg...) if (core_debug) \ | 95 | #define dprintk(fmt, arg...) if (core_debug) \ |
96 | printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) | 96 | printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) |
97 | 97 | ||
98 | /* ------------------------------------------------------------------ */ | ||
99 | /* debug help functions */ | ||
100 | |||
101 | static const char *v4l1_ioctls[] = { | ||
102 | "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", | ||
103 | "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", | ||
104 | "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", | ||
105 | "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", | ||
106 | "SMICROCODE", "GVBIFMT", "SVBIFMT" }; | ||
107 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
108 | |||
109 | static const char *v4l2_ioctls[] = { | ||
110 | "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", | ||
111 | "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", | ||
112 | "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", | ||
113 | "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", | ||
114 | "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", | ||
115 | "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", | ||
116 | "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", | ||
117 | "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", | ||
118 | "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", | ||
119 | "S_MODULATOR" | ||
120 | }; | ||
121 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | ||
122 | |||
123 | static const char *osspcm_ioctls[] = { | ||
124 | "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT", | ||
125 | "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS", | ||
126 | "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER", | ||
127 | "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO", | ||
128 | "SETDUPLEX", "GETODELAY" | ||
129 | }; | ||
130 | #define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls) | ||
131 | |||
132 | void saa7134_print_ioctl(char *name, unsigned int cmd) | ||
133 | { | ||
134 | char *dir; | ||
135 | |||
136 | switch (_IOC_DIR(cmd)) { | ||
137 | case _IOC_NONE: dir = "--"; break; | ||
138 | case _IOC_READ: dir = "r-"; break; | ||
139 | case _IOC_WRITE: dir = "-w"; break; | ||
140 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
141 | default: dir = "??"; break; | ||
142 | } | ||
143 | switch (_IOC_TYPE(cmd)) { | ||
144 | case 'v': | ||
145 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", | ||
146 | name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? | ||
147 | v4l1_ioctls[_IOC_NR(cmd)] : "???"); | ||
148 | break; | ||
149 | case 'V': | ||
150 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", | ||
151 | name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? | ||
152 | v4l2_ioctls[_IOC_NR(cmd)] : "???"); | ||
153 | break; | ||
154 | case 'P': | ||
155 | printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n", | ||
156 | name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ? | ||
157 | osspcm_ioctls[_IOC_NR(cmd)] : "???"); | ||
158 | break; | ||
159 | case 'M': | ||
160 | printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n", | ||
161 | name, cmd, dir, _IOC_NR(cmd)); | ||
162 | break; | ||
163 | default: | ||
164 | printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", | ||
165 | name, cmd, dir, _IOC_NR(cmd)); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) | 98 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) |
170 | { | 99 | { |
171 | unsigned long mode,status; | 100 | unsigned long mode,status; |
@@ -211,7 +140,7 @@ static int pending_call(struct notifier_block *self, unsigned long state, | |||
211 | return NOTIFY_DONE; | 140 | return NOTIFY_DONE; |
212 | } | 141 | } |
213 | 142 | ||
214 | static int pending_registered; | 143 | static int pending_registered=0; |
215 | static struct notifier_block pending_notifier = { | 144 | static struct notifier_block pending_notifier = { |
216 | .notifier_call = pending_call, | 145 | .notifier_call = pending_call, |
217 | }; | 146 | }; |
@@ -610,11 +539,38 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
610 | card_has_mpeg(dev)) | 539 | card_has_mpeg(dev)) |
611 | saa7134_irq_ts_done(dev,status); | 540 | saa7134_irq_ts_done(dev,status); |
612 | 541 | ||
613 | if ((report & (SAA7134_IRQ_REPORT_GPIO16 | | 542 | if (report & SAA7134_IRQ_REPORT_GPIO16) { |
614 | SAA7134_IRQ_REPORT_GPIO18)) && | 543 | switch (dev->has_remote) { |
615 | dev->remote) | 544 | case SAA7134_REMOTE_GPIO: |
616 | saa7134_input_irq(dev); | 545 | if (dev->remote->mask_keydown & 0x10000) { |
546 | saa7134_input_irq(dev); | ||
547 | } | ||
548 | break; | ||
549 | |||
550 | case SAA7134_REMOTE_I2C: | ||
551 | break; /* FIXME: invoke I2C get_key() */ | ||
617 | 552 | ||
553 | default: /* GPIO16 not used by IR remote */ | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | if (report & SAA7134_IRQ_REPORT_GPIO18) { | ||
559 | switch (dev->has_remote) { | ||
560 | case SAA7134_REMOTE_GPIO: | ||
561 | if ((dev->remote->mask_keydown & 0x40000) || | ||
562 | (dev->remote->mask_keyup & 0x40000)) { | ||
563 | saa7134_input_irq(dev); | ||
564 | } | ||
565 | break; | ||
566 | |||
567 | case SAA7134_REMOTE_I2C: | ||
568 | break; /* FIXME: invoke I2C get_key() */ | ||
569 | |||
570 | default: /* GPIO18 not used by IR remote */ | ||
571 | break; | ||
572 | } | ||
573 | } | ||
618 | } | 574 | } |
619 | 575 | ||
620 | if (10 == loop) { | 576 | if (10 == loop) { |
@@ -624,13 +580,16 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
624 | printk(KERN_WARNING "%s/irq: looping -- " | 580 | printk(KERN_WARNING "%s/irq: looping -- " |
625 | "clearing PE (parity error!) enable bit\n",dev->name); | 581 | "clearing PE (parity error!) enable bit\n",dev->name); |
626 | saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); | 582 | saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); |
627 | } else if (report & (SAA7134_IRQ_REPORT_GPIO16 | | 583 | } else if (report & SAA7134_IRQ_REPORT_GPIO16) { |
628 | SAA7134_IRQ_REPORT_GPIO18)) { | 584 | /* disable gpio16 IRQ */ |
629 | /* disable gpio IRQs */ | ||
630 | printk(KERN_WARNING "%s/irq: looping -- " | 585 | printk(KERN_WARNING "%s/irq: looping -- " |
631 | "clearing GPIO enable bits\n",dev->name); | 586 | "clearing GPIO16 enable bit\n",dev->name); |
632 | saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 | | 587 | saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16); |
633 | SAA7134_IRQ2_INTE_GPIO18)); | 588 | } else if (report & SAA7134_IRQ_REPORT_GPIO18) { |
589 | /* disable gpio18 IRQs */ | ||
590 | printk(KERN_WARNING "%s/irq: looping -- " | ||
591 | "clearing GPIO18 enable bit\n",dev->name); | ||
592 | saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); | ||
634 | } else { | 593 | } else { |
635 | /* disable all irqs */ | 594 | /* disable all irqs */ |
636 | printk(KERN_WARNING "%s/irq: looping -- " | 595 | printk(KERN_WARNING "%s/irq: looping -- " |
@@ -711,10 +670,14 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) | |||
711 | SAA7134_IRQ2_INTE_PE | | 670 | SAA7134_IRQ2_INTE_PE | |
712 | SAA7134_IRQ2_INTE_AR; | 671 | SAA7134_IRQ2_INTE_AR; |
713 | 672 | ||
714 | if (dev->has_remote == SAA7134_REMOTE_GPIO) | 673 | if (dev->has_remote == SAA7134_REMOTE_GPIO) { |
715 | irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | | 674 | if (dev->remote->mask_keydown & 0x10000) |
716 | SAA7134_IRQ2_INTE_GPIO18A | | 675 | irq2_mask |= SAA7134_IRQ2_INTE_GPIO16; |
717 | SAA7134_IRQ2_INTE_GPIO16 ); | 676 | else if (dev->remote->mask_keydown & 0x40000) |
677 | irq2_mask |= SAA7134_IRQ2_INTE_GPIO18; | ||
678 | else if (dev->remote->mask_keyup & 0x40000) | ||
679 | irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A; | ||
680 | } | ||
718 | 681 | ||
719 | saa_writel(SAA7134_IRQ1, 0); | 682 | saa_writel(SAA7134_IRQ1, 0); |
720 | saa_writel(SAA7134_IRQ2, irq2_mask); | 683 | saa_writel(SAA7134_IRQ2, irq2_mask); |
@@ -1156,7 +1119,7 @@ static int saa7134_init(void) | |||
1156 | printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n", | 1119 | printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n", |
1157 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | 1120 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); |
1158 | #endif | 1121 | #endif |
1159 | return pci_module_init(&saa7134_pci_driver); | 1122 | return pci_register_driver(&saa7134_pci_driver); |
1160 | } | 1123 | } |
1161 | 1124 | ||
1162 | static void saa7134_fini(void) | 1125 | static void saa7134_fini(void) |
@@ -1173,7 +1136,6 @@ module_exit(saa7134_fini); | |||
1173 | 1136 | ||
1174 | /* ----------------------------------------------------------- */ | 1137 | /* ----------------------------------------------------------- */ |
1175 | 1138 | ||
1176 | EXPORT_SYMBOL(saa7134_print_ioctl); | ||
1177 | EXPORT_SYMBOL(saa7134_i2c_call_clients); | 1139 | EXPORT_SYMBOL(saa7134_i2c_call_clients); |
1178 | EXPORT_SYMBOL(saa7134_devlist); | 1140 | EXPORT_SYMBOL(saa7134_devlist); |
1179 | EXPORT_SYMBOL(saa7134_boards); | 1141 | EXPORT_SYMBOL(saa7134_boards); |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index e016480c3468..399f9952596c 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "saa7134-reg.h" | 32 | #include "saa7134-reg.h" |
33 | #include "saa7134.h" | 33 | #include "saa7134.h" |
34 | #include <media/v4l2-common.h> | ||
34 | 35 | ||
35 | #ifdef HAVE_MT352 | 36 | #ifdef HAVE_MT352 |
36 | # include "mt352.h" | 37 | # include "mt352.h" |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 575f3e835f91..bd4c389d4c37 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "saa7134.h" | 29 | #include "saa7134.h" |
30 | 30 | ||
31 | #include <media/saa6752hs.h> | 31 | #include <media/saa6752hs.h> |
32 | #include <media/v4l2-common.h> | ||
32 | 33 | ||
33 | /* ------------------------------------------------------------------ */ | 34 | /* ------------------------------------------------------------------ */ |
34 | 35 | ||
@@ -163,7 +164,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, | |||
163 | struct saa7134_dev *dev = file->private_data; | 164 | struct saa7134_dev *dev = file->private_data; |
164 | 165 | ||
165 | if (debug > 1) | 166 | if (debug > 1) |
166 | saa7134_print_ioctl(dev->name,cmd); | 167 | v4l_print_ioctl(dev->name,cmd); |
167 | switch (cmd) { | 168 | switch (cmd) { |
168 | case VIDIOC_QUERYCAP: | 169 | case VIDIOC_QUERYCAP: |
169 | { | 170 | { |
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 1792d03d621d..6162550c4136 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include "saa7134-reg.h" | 31 | #include "saa7134-reg.h" |
32 | #include "saa7134.h" | 32 | #include "saa7134.h" |
33 | #include <media/v4l2-common.h> | ||
33 | 34 | ||
34 | /* ----------------------------------------------------------- */ | 35 | /* ----------------------------------------------------------- */ |
35 | 36 | ||
@@ -390,9 +391,7 @@ static struct i2c_algorithm saa7134_algo = { | |||
390 | 391 | ||
391 | static struct i2c_adapter saa7134_adap_template = { | 392 | static struct i2c_adapter saa7134_adap_template = { |
392 | .owner = THIS_MODULE, | 393 | .owner = THIS_MODULE, |
393 | #ifdef I2C_CLASS_TV_ANALOG | ||
394 | .class = I2C_CLASS_TV_ANALOG, | 394 | .class = I2C_CLASS_TV_ANALOG, |
395 | #endif | ||
396 | .name = "saa7134", | 395 | .name = "saa7134", |
397 | .id = I2C_HW_SAA7134, | 396 | .id = I2C_HW_SAA7134, |
398 | .algo = &saa7134_algo, | 397 | .algo = &saa7134_algo, |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ab75ca5ac356..82d28cbf289f 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -56,23 +56,23 @@ static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = { | |||
56 | [ 12 ] = KEY_KP8, | 56 | [ 12 ] = KEY_KP8, |
57 | [ 13 ] = KEY_KP9, | 57 | [ 13 ] = KEY_KP9, |
58 | 58 | ||
59 | [ 14 ] = KEY_TUNER, // Air/Cable | 59 | [ 14 ] = KEY_MODE, // Air/Cable |
60 | [ 17 ] = KEY_VIDEO, // Video | 60 | [ 17 ] = KEY_VIDEO, // Video |
61 | [ 21 ] = KEY_AUDIO, // Audio | 61 | [ 21 ] = KEY_AUDIO, // Audio |
62 | [ 0 ] = KEY_POWER, // Pover | 62 | [ 0 ] = KEY_POWER, // Power |
63 | [ 24 ] = KEY_TUNER, // AV Source | ||
63 | [ 2 ] = KEY_ZOOM, // Fullscreen | 64 | [ 2 ] = KEY_ZOOM, // Fullscreen |
65 | [ 26 ] = KEY_LANGUAGE, // Stereo | ||
64 | [ 27 ] = KEY_MUTE, // Mute | 66 | [ 27 ] = KEY_MUTE, // Mute |
65 | [ 20 ] = KEY_VOLUMEUP, | 67 | [ 20 ] = KEY_VOLUMEUP, // Volume + |
66 | [ 23 ] = KEY_VOLUMEDOWN, | 68 | [ 23 ] = KEY_VOLUMEDOWN, // Volume - |
67 | [ 18 ] = KEY_CHANNELUP, // Channel + | 69 | [ 18 ] = KEY_CHANNELUP, // Channel + |
68 | [ 19 ] = KEY_CHANNELDOWN, // Channel - | 70 | [ 19 ] = KEY_CHANNELDOWN, // Channel - |
69 | [ 6 ] = KEY_AGAIN, // Recal | 71 | [ 6 ] = KEY_AGAIN, // Recall |
70 | [ 16 ] = KEY_KPENTER, // Enter | 72 | [ 16 ] = KEY_ENTER, // Enter |
71 | |||
72 | [ 26 ] = KEY_F22, // Stereo | ||
73 | [ 24 ] = KEY_EDIT, // AV Source | ||
74 | }; | 73 | }; |
75 | 74 | ||
75 | |||
76 | static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { | 76 | static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { |
77 | [ 0 ] = KEY_KP0, | 77 | [ 0 ] = KEY_KP0, |
78 | [ 1 ] = KEY_KP1, | 78 | [ 1 ] = KEY_KP1, |
@@ -543,12 +543,22 @@ static int build_key(struct saa7134_dev *dev) | |||
543 | dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", | 543 | dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", |
544 | gpio, ir->mask_keycode, data); | 544 | gpio, ir->mask_keycode, data); |
545 | 545 | ||
546 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || | 546 | if (ir->polling) { |
547 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { | 547 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || |
548 | ir_input_keydown(ir->dev, &ir->ir, data, data); | 548 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { |
549 | } else { | 549 | ir_input_keydown(ir->dev, &ir->ir, data, data); |
550 | ir_input_nokey(ir->dev, &ir->ir); | 550 | } else { |
551 | ir_input_nokey(ir->dev, &ir->ir); | ||
552 | } | ||
553 | } | ||
554 | else { /* IRQ driven mode - handle key press and release in one go */ | ||
555 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || | ||
556 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { | ||
557 | ir_input_keydown(ir->dev, &ir->ir, data, data); | ||
558 | ir_input_nokey(ir->dev, &ir->ir); | ||
559 | } | ||
551 | } | 560 | } |
561 | |||
552 | return 0; | 562 | return 0; |
553 | } | 563 | } |
554 | 564 | ||
@@ -686,6 +696,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
686 | polling = 50; // ms | 696 | polling = 50; // ms |
687 | break; | 697 | break; |
688 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 698 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
699 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: | ||
689 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: | 700 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: |
690 | ir_codes = videomate_tv_pvr_codes; | 701 | ir_codes = videomate_tv_pvr_codes; |
691 | mask_keycode = 0x00003F; | 702 | mask_keycode = 0x00003F; |
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index 8badd2a9cb2f..7448e386a804 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c | |||
@@ -373,6 +373,42 @@ static ssize_t dsp_write(struct file *file, const char __user *buffer, | |||
373 | return -EINVAL; | 373 | return -EINVAL; |
374 | } | 374 | } |
375 | 375 | ||
376 | static const char *osspcm_ioctls[] = { | ||
377 | "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT", | ||
378 | "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS", | ||
379 | "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER", | ||
380 | "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO", | ||
381 | "SETDUPLEX", "GETODELAY" | ||
382 | }; | ||
383 | #define OSSPCM_IOCTLS ARRAY_SIZE(osspcm_ioctls) | ||
384 | |||
385 | static void saa7134_oss_print_ioctl(char *name, unsigned int cmd) | ||
386 | { | ||
387 | char *dir; | ||
388 | |||
389 | switch (_IOC_DIR(cmd)) { | ||
390 | case _IOC_NONE: dir = "--"; break; | ||
391 | case _IOC_READ: dir = "r-"; break; | ||
392 | case _IOC_WRITE: dir = "-w"; break; | ||
393 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
394 | default: dir = "??"; break; | ||
395 | } | ||
396 | switch (_IOC_TYPE(cmd)) { | ||
397 | case 'P': | ||
398 | printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n", | ||
399 | name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ? | ||
400 | osspcm_ioctls[_IOC_NR(cmd)] : "???"); | ||
401 | break; | ||
402 | case 'M': | ||
403 | printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n", | ||
404 | name, cmd, dir, _IOC_NR(cmd)); | ||
405 | break; | ||
406 | default: | ||
407 | printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", | ||
408 | name, cmd, dir, _IOC_NR(cmd)); | ||
409 | } | ||
410 | } | ||
411 | |||
376 | static int dsp_ioctl(struct inode *inode, struct file *file, | 412 | static int dsp_ioctl(struct inode *inode, struct file *file, |
377 | unsigned int cmd, unsigned long arg) | 413 | unsigned int cmd, unsigned long arg) |
378 | { | 414 | { |
@@ -382,7 +418,7 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
382 | int val = 0; | 418 | int val = 0; |
383 | 419 | ||
384 | if (debug > 1) | 420 | if (debug > 1) |
385 | saa7134_print_ioctl(dev->name,cmd); | 421 | saa7134_oss_print_ioctl(dev->name,cmd); |
386 | switch (cmd) { | 422 | switch (cmd) { |
387 | case OSS_GETVERSION: | 423 | case OSS_GETVERSION: |
388 | return put_user(SOUND_VERSION, p); | 424 | return put_user(SOUND_VERSION, p); |
@@ -678,7 +714,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, | |||
678 | int __user *p = argp; | 714 | int __user *p = argp; |
679 | 715 | ||
680 | if (debug > 1) | 716 | if (debug > 1) |
681 | saa7134_print_ioctl(dev->name,cmd); | 717 | saa7134_oss_print_ioctl(dev->name,cmd); |
682 | switch (cmd) { | 718 | switch (cmd) { |
683 | case OSS_GETVERSION: | 719 | case OSS_GETVERSION: |
684 | return put_user(SOUND_VERSION, p); | 720 | return put_user(SOUND_VERSION, p); |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 45c852df13ed..adfa8fe49a11 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include "saa7134-reg.h" | 30 | #include "saa7134-reg.h" |
31 | #include "saa7134.h" | 31 | #include "saa7134.h" |
32 | #include <media/v4l2-common.h> | ||
32 | 33 | ||
33 | /* Include V4L1 specific functions. Should be removed soon */ | 34 | /* Include V4L1 specific functions. Should be removed soon */ |
34 | #include <linux/videodev.h> | 35 | #include <linux/videodev.h> |
@@ -1689,7 +1690,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1689 | int err; | 1690 | int err; |
1690 | 1691 | ||
1691 | if (video_debug > 1) | 1692 | if (video_debug > 1) |
1692 | saa7134_print_ioctl(dev->name,cmd); | 1693 | v4l_print_ioctl(dev->name,cmd); |
1693 | 1694 | ||
1694 | switch (cmd) { | 1695 | switch (cmd) { |
1695 | case VIDIOC_S_CTRL: | 1696 | case VIDIOC_S_CTRL: |
@@ -2142,7 +2143,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
2142 | struct saa7134_dev *dev = fh->dev; | 2143 | struct saa7134_dev *dev = fh->dev; |
2143 | 2144 | ||
2144 | if (video_debug > 1) | 2145 | if (video_debug > 1) |
2145 | saa7134_print_ioctl(dev->name,cmd); | 2146 | v4l_print_ioctl(dev->name,cmd); |
2146 | switch (cmd) { | 2147 | switch (cmd) { |
2147 | case VIDIOC_QUERYCAP: | 2148 | case VIDIOC_QUERYCAP: |
2148 | { | 2149 | { |
@@ -2262,6 +2263,7 @@ static struct file_operations video_fops = | |||
2262 | .poll = video_poll, | 2263 | .poll = video_poll, |
2263 | .mmap = video_mmap, | 2264 | .mmap = video_mmap, |
2264 | .ioctl = video_ioctl, | 2265 | .ioctl = video_ioctl, |
2266 | .compat_ioctl = v4l_compat_ioctl32, | ||
2265 | .llseek = no_llseek, | 2267 | .llseek = no_llseek, |
2266 | }; | 2268 | }; |
2267 | 2269 | ||
@@ -2271,6 +2273,7 @@ static struct file_operations radio_fops = | |||
2271 | .open = video_open, | 2273 | .open = video_open, |
2272 | .release = video_release, | 2274 | .release = video_release, |
2273 | .ioctl = radio_ioctl, | 2275 | .ioctl = radio_ioctl, |
2276 | .compat_ioctl = v4l_compat_ioctl32, | ||
2274 | .llseek = no_llseek, | 2277 | .llseek = no_llseek, |
2275 | }; | 2278 | }; |
2276 | 2279 | ||
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index add49db1ad41..e70eae8d29bb 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -37,6 +37,9 @@ | |||
37 | #include <media/ir-common.h> | 37 | #include <media/ir-common.h> |
38 | #include <media/ir-kbd-i2c.h> | 38 | #include <media/ir-kbd-i2c.h> |
39 | #include <media/video-buf.h> | 39 | #include <media/video-buf.h> |
40 | #include <sound/driver.h> | ||
41 | #include <sound/core.h> | ||
42 | #include <sound/pcm.h> | ||
40 | #include <media/video-buf-dvb.h> | 43 | #include <media/video-buf-dvb.h> |
41 | 44 | ||
42 | #ifndef TRUE | 45 | #ifndef TRUE |
@@ -47,10 +50,6 @@ | |||
47 | #endif | 50 | #endif |
48 | #define UNSET (-1U) | 51 | #define UNSET (-1U) |
49 | 52 | ||
50 | #include <sound/driver.h> | ||
51 | #include <sound/core.h> | ||
52 | #include <sound/pcm.h> | ||
53 | |||
54 | /* ----------------------------------------------------------- */ | 53 | /* ----------------------------------------------------------- */ |
55 | /* enums */ | 54 | /* enums */ |
56 | 55 | ||
@@ -209,6 +208,8 @@ struct saa7134_format { | |||
209 | #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 | 208 | #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 |
210 | #define SAA7134_BOARD_PHILIPS_TIGER 81 | 209 | #define SAA7134_BOARD_PHILIPS_TIGER 81 |
211 | #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 | 210 | #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 |
211 | #define SAA7134_BOARD_CINERGY250PCI 83 | ||
212 | #define SAA7134_BOARD_FLYDVB_TRIO 84 | ||
212 | 213 | ||
213 | #define SAA7134_MAXBOARDS 8 | 214 | #define SAA7134_MAXBOARDS 8 |
214 | #define SAA7134_INPUT_MAX 8 | 215 | #define SAA7134_INPUT_MAX 8 |
@@ -546,7 +547,6 @@ struct saa7134_dev { | |||
546 | 547 | ||
547 | extern struct list_head saa7134_devlist; | 548 | extern struct list_head saa7134_devlist; |
548 | 549 | ||
549 | void saa7134_print_ioctl(char *name, unsigned int cmd); | ||
550 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); | 550 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); |
551 | 551 | ||
552 | #define SAA7134_PGTABLE_SIZE 4096 | 552 | #define SAA7134_PGTABLE_SIZE 4096 |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index d4497dbae05c..6ee54a45411f 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -1974,6 +1974,7 @@ static struct file_operations saa_fops = | |||
1974 | .open = saa_open, | 1974 | .open = saa_open, |
1975 | .release = saa_release, | 1975 | .release = saa_release, |
1976 | .ioctl = saa_ioctl, | 1976 | .ioctl = saa_ioctl, |
1977 | .compat_ioctl = v4l_compat_ioctl32, | ||
1977 | .read = saa_read, | 1978 | .read = saa_read, |
1978 | .llseek = no_llseek, | 1979 | .llseek = no_llseek, |
1979 | .write = saa_write, | 1980 | .write = saa_write, |
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 549c9929f107..99261f15e66e 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #include "bttv.h" | 51 | #include "bttv.h" |
52 | #include <media/audiochip.h> | 52 | #include <media/audiochip.h> |
53 | #include <media/v4l2-common.h> | ||
53 | 54 | ||
54 | #ifndef VIDEO_AUDIO_BALANCE | 55 | #ifndef VIDEO_AUDIO_BALANCE |
55 | # define VIDEO_AUDIO_BALANCE 32 | 56 | # define VIDEO_AUDIO_BALANCE 32 |
@@ -90,9 +91,6 @@ struct tda7432 { | |||
90 | static struct i2c_driver driver; | 91 | static struct i2c_driver driver; |
91 | static struct i2c_client client_template; | 92 | static struct i2c_client client_template; |
92 | 93 | ||
93 | #define dprintk if (debug) printk | ||
94 | #define d2printk if (debug > 1) printk | ||
95 | |||
96 | /* The TDA7432 is made by STS-Thompson | 94 | /* The TDA7432 is made by STS-Thompson |
97 | * http://www.st.com | 95 | * http://www.st.com |
98 | * http://us.st.com/stonline/books/pdf/docs/4056.pdf | 96 | * http://us.st.com/stonline/books/pdf/docs/4056.pdf |
@@ -229,12 +227,12 @@ static struct i2c_client client_template; | |||
229 | static int tda7432_write(struct i2c_client *client, int subaddr, int val) | 227 | static int tda7432_write(struct i2c_client *client, int subaddr, int val) |
230 | { | 228 | { |
231 | unsigned char buffer[2]; | 229 | unsigned char buffer[2]; |
232 | d2printk("tda7432: In tda7432_write\n"); | 230 | v4l_dbg(2,client,"In tda7432_write\n"); |
233 | dprintk("tda7432: Writing %d 0x%x\n", subaddr, val); | 231 | v4l_dbg(1,client,"Writing %d 0x%x\n", subaddr, val); |
234 | buffer[0] = subaddr; | 232 | buffer[0] = subaddr; |
235 | buffer[1] = val; | 233 | buffer[1] = val; |
236 | if (2 != i2c_master_send(client,buffer,2)) { | 234 | if (2 != i2c_master_send(client,buffer,2)) { |
237 | printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n", | 235 | v4l_err(client,"I/O error, trying (write %d 0x%x)\n", |
238 | subaddr, val); | 236 | subaddr, val); |
239 | return -1; | 237 | return -1; |
240 | } | 238 | } |
@@ -247,9 +245,9 @@ static int tda7432_set(struct i2c_client *client) | |||
247 | { | 245 | { |
248 | struct tda7432 *t = i2c_get_clientdata(client); | 246 | struct tda7432 *t = i2c_get_clientdata(client); |
249 | unsigned char buf[16]; | 247 | unsigned char buf[16]; |
250 | d2printk("tda7432: In tda7432_set\n"); | 248 | v4l_dbg(2,client,"In tda7432_set\n"); |
251 | 249 | ||
252 | dprintk(KERN_INFO | 250 | v4l_dbg(1,client, |
253 | "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", | 251 | "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", |
254 | t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud); | 252 | t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud); |
255 | buf[0] = TDA7432_IN; | 253 | buf[0] = TDA7432_IN; |
@@ -263,7 +261,7 @@ static int tda7432_set(struct i2c_client *client) | |||
263 | buf[8] = t->rr; | 261 | buf[8] = t->rr; |
264 | buf[9] = t->loud; | 262 | buf[9] = t->loud; |
265 | if (10 != i2c_master_send(client,buf,10)) { | 263 | if (10 != i2c_master_send(client,buf,10)) { |
266 | printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n"); | 264 | v4l_err(client,"I/O error, trying tda7432_set\n"); |
267 | return -1; | 265 | return -1; |
268 | } | 266 | } |
269 | 267 | ||
@@ -273,7 +271,7 @@ static int tda7432_set(struct i2c_client *client) | |||
273 | static void do_tda7432_init(struct i2c_client *client) | 271 | static void do_tda7432_init(struct i2c_client *client) |
274 | { | 272 | { |
275 | struct tda7432 *t = i2c_get_clientdata(client); | 273 | struct tda7432 *t = i2c_get_clientdata(client); |
276 | d2printk("tda7432: In tda7432_init\n"); | 274 | v4l_dbg(2,client,"In tda7432_init\n"); |
277 | 275 | ||
278 | t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ | 276 | t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ |
279 | TDA7432_BASS_SYM | /* Symmetric bass cut */ | 277 | TDA7432_BASS_SYM | /* Symmetric bass cut */ |
@@ -301,7 +299,6 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) | |||
301 | { | 299 | { |
302 | struct tda7432 *t; | 300 | struct tda7432 *t; |
303 | struct i2c_client *client; | 301 | struct i2c_client *client; |
304 | d2printk("tda7432: In tda7432_attach\n"); | ||
305 | 302 | ||
306 | t = kmalloc(sizeof *t,GFP_KERNEL); | 303 | t = kmalloc(sizeof *t,GFP_KERNEL); |
307 | if (!t) | 304 | if (!t) |
@@ -315,21 +312,16 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) | |||
315 | i2c_set_clientdata(client, t); | 312 | i2c_set_clientdata(client, t); |
316 | 313 | ||
317 | do_tda7432_init(client); | 314 | do_tda7432_init(client); |
318 | printk(KERN_INFO "tda7432: init\n"); | ||
319 | |||
320 | i2c_attach_client(client); | 315 | i2c_attach_client(client); |
316 | |||
317 | v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name); | ||
321 | return 0; | 318 | return 0; |
322 | } | 319 | } |
323 | 320 | ||
324 | static int tda7432_probe(struct i2c_adapter *adap) | 321 | static int tda7432_probe(struct i2c_adapter *adap) |
325 | { | 322 | { |
326 | #ifdef I2C_CLASS_TV_ANALOG | ||
327 | if (adap->class & I2C_CLASS_TV_ANALOG) | 323 | if (adap->class & I2C_CLASS_TV_ANALOG) |
328 | return i2c_probe(adap, &addr_data, tda7432_attach); | 324 | return i2c_probe(adap, &addr_data, tda7432_attach); |
329 | #else | ||
330 | if (adap->id == I2C_HW_B_BT848) | ||
331 | return i2c_probe(adap, &addr_data, tda7432_attach); | ||
332 | #endif | ||
333 | return 0; | 325 | return 0; |
334 | } | 326 | } |
335 | 327 | ||
@@ -348,7 +340,9 @@ static int tda7432_command(struct i2c_client *client, | |||
348 | unsigned int cmd, void *arg) | 340 | unsigned int cmd, void *arg) |
349 | { | 341 | { |
350 | struct tda7432 *t = i2c_get_clientdata(client); | 342 | struct tda7432 *t = i2c_get_clientdata(client); |
351 | d2printk("tda7432: In tda7432_command\n"); | 343 | v4l_dbg(2,client,"In tda7432_command\n"); |
344 | if (debug>1) | ||
345 | v4l_i2c_print_ioctl(client,cmd); | ||
352 | 346 | ||
353 | switch (cmd) { | 347 | switch (cmd) { |
354 | /* --- v4l ioctls --- */ | 348 | /* --- v4l ioctls --- */ |
@@ -359,7 +353,6 @@ static int tda7432_command(struct i2c_client *client, | |||
359 | case VIDIOCGAUDIO: | 353 | case VIDIOCGAUDIO: |
360 | { | 354 | { |
361 | struct video_audio *va = arg; | 355 | struct video_audio *va = arg; |
362 | dprintk("tda7432: VIDIOCGAUDIO\n"); | ||
363 | 356 | ||
364 | va->flags |= VIDEO_AUDIO_VOLUME | | 357 | va->flags |= VIDEO_AUDIO_VOLUME | |
365 | VIDEO_AUDIO_BASS | | 358 | VIDEO_AUDIO_BASS | |
@@ -414,7 +407,6 @@ static int tda7432_command(struct i2c_client *client, | |||
414 | case VIDIOCSAUDIO: | 407 | case VIDIOCSAUDIO: |
415 | { | 408 | { |
416 | struct video_audio *va = arg; | 409 | struct video_audio *va = arg; |
417 | dprintk("tda7432: VIDEOCSAUDIO\n"); | ||
418 | 410 | ||
419 | if(va->flags & VIDEO_AUDIO_VOLUME){ | 411 | if(va->flags & VIDEO_AUDIO_VOLUME){ |
420 | if(!maxvol){ /* max +20db */ | 412 | if(!maxvol){ /* max +20db */ |
@@ -490,11 +482,6 @@ static int tda7432_command(struct i2c_client *client, | |||
490 | 482 | ||
491 | } /* end of VIDEOCSAUDIO case */ | 483 | } /* end of VIDEOCSAUDIO case */ |
492 | 484 | ||
493 | default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */ | ||
494 | |||
495 | /* nothing */ | ||
496 | d2printk("tda7432: Default\n"); | ||
497 | |||
498 | } /* end of (cmd) switch */ | 485 | } /* end of (cmd) switch */ |
499 | 486 | ||
500 | return 0; | 487 | return 0; |
@@ -502,7 +489,7 @@ static int tda7432_command(struct i2c_client *client, | |||
502 | 489 | ||
503 | static struct i2c_driver driver = { | 490 | static struct i2c_driver driver = { |
504 | .driver = { | 491 | .driver = { |
505 | .name = "i2c tda7432 driver", | 492 | .name = "tda7432", |
506 | }, | 493 | }, |
507 | .id = I2C_DRIVERID_TDA7432, | 494 | .id = I2C_DRIVERID_TDA7432, |
508 | .attach_adapter = tda7432_probe, | 495 | .attach_adapter = tda7432_probe, |
@@ -519,7 +506,7 @@ static struct i2c_client client_template = | |||
519 | static int __init tda7432_init(void) | 506 | static int __init tda7432_init(void) |
520 | { | 507 | { |
521 | if ( (loudness < 0) || (loudness > 15) ) { | 508 | if ( (loudness < 0) || (loudness > 15) ) { |
522 | printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n"); | 509 | printk(KERN_ERR "loudness parameter must be between 0 and 15\n"); |
523 | return -EINVAL; | 510 | return -EINVAL; |
524 | } | 511 | } |
525 | 512 | ||
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 61d94ddaff41..2498b76df429 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -398,14 +398,8 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
398 | return 0; | 398 | return 0; |
399 | } | 399 | } |
400 | 400 | ||
401 | |||
402 | /*---------------------------------------------------------------------*/ | 401 | /*---------------------------------------------------------------------*/ |
403 | 402 | ||
404 | #define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) | ||
405 | #define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) | ||
406 | #define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) | ||
407 | #define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) | ||
408 | |||
409 | static void set_audio(struct tuner *t) | 403 | static void set_audio(struct tuner *t) |
410 | { | 404 | { |
411 | char* mode; | 405 | char* mode; |
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 9c3ecf7a0fed..299393bf900a 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c | |||
@@ -257,13 +257,8 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) | |||
257 | 257 | ||
258 | static int tda9875_probe(struct i2c_adapter *adap) | 258 | static int tda9875_probe(struct i2c_adapter *adap) |
259 | { | 259 | { |
260 | #ifdef I2C_CLASS_TV_ANALOG | ||
261 | if (adap->class & I2C_CLASS_TV_ANALOG) | 260 | if (adap->class & I2C_CLASS_TV_ANALOG) |
262 | return i2c_probe(adap, &addr_data, tda9875_attach); | 261 | return i2c_probe(adap, &addr_data, tda9875_attach); |
263 | #else | ||
264 | if (adap->id == I2C_HW_B_BT848) | ||
265 | return i2c_probe(adap, &addr_data, tda9875_attach); | ||
266 | #endif | ||
267 | return 0; | 262 | return 0; |
268 | } | 263 | } |
269 | 264 | ||
@@ -373,7 +368,7 @@ static int tda9875_command(struct i2c_client *client, | |||
373 | 368 | ||
374 | static struct i2c_driver driver = { | 369 | static struct i2c_driver driver = { |
375 | .driver = { | 370 | .driver = { |
376 | .name = "i2c tda9875 driver", | 371 | .name = "tda9875", |
377 | }, | 372 | }, |
378 | .id = I2C_DRIVERID_TDA9875, | 373 | .id = I2C_DRIVERID_TDA9875, |
379 | .attach_adapter = tda9875_probe, | 374 | .attach_adapter = tda9875_probe, |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 7165a1b9625a..9cf47dc65579 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | 11 | ||
12 | #include <media/audiochip.h> | 12 | #include <media/v4l2-common.h> |
13 | #include <media/tuner.h> | 13 | #include <media/tuner.h> |
14 | 14 | ||
15 | 15 | ||
@@ -57,7 +57,6 @@ struct tda9887 { | |||
57 | v4l2_std_id std; | 57 | v4l2_std_id std; |
58 | enum tuner_mode mode; | 58 | enum tuner_mode mode; |
59 | unsigned int config; | 59 | unsigned int config; |
60 | unsigned int pinnacle_id; | ||
61 | unsigned int using_v4l2; | 60 | unsigned int using_v4l2; |
62 | unsigned int radio_mode; | 61 | unsigned int radio_mode; |
63 | unsigned char data[4]; | 62 | unsigned char data[4]; |
@@ -115,6 +114,9 @@ static struct i2c_client client_template; | |||
115 | #define cAudioGain0 0x00 // bit c7 | 114 | #define cAudioGain0 0x00 // bit c7 |
116 | #define cAudioGain6 0x80 // bit c7 | 115 | #define cAudioGain6 0x80 // bit c7 |
117 | 116 | ||
117 | #define cTopMask 0x1f // bit c0:4 | ||
118 | #define cTopPalSecamDefault 0x14 // bit c0:4 | ||
119 | #define cTopNtscRadioDefault 0x10 // bit c0:4 | ||
118 | 120 | ||
119 | //// third reg (e) | 121 | //// third reg (e) |
120 | #define cAudioIF_4_5 0x00 // bit e0:1 | 122 | #define cAudioIF_4_5 0x00 // bit e0:1 |
@@ -146,13 +148,15 @@ static struct i2c_client client_template; | |||
146 | 148 | ||
147 | static struct tvnorm tvnorms[] = { | 149 | static struct tvnorm tvnorms[] = { |
148 | { | 150 | { |
149 | .std = V4L2_STD_PAL_BG, | 151 | .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N, |
150 | .name = "PAL-BG", | 152 | .name = "PAL-BGHN", |
151 | .b = ( cNegativeFmTV | | 153 | .b = ( cNegativeFmTV | |
152 | cQSS ), | 154 | cQSS ), |
153 | .c = ( cDeemphasisON | | 155 | .c = ( cDeemphasisON | |
154 | cDeemphasis50 ), | 156 | cDeemphasis50 | |
155 | .e = ( cAudioIF_5_5 | | 157 | cTopPalSecamDefault), |
158 | .e = ( cGating_36 | | ||
159 | cAudioIF_5_5 | | ||
156 | cVideoIF_38_90 ), | 160 | cVideoIF_38_90 ), |
157 | },{ | 161 | },{ |
158 | .std = V4L2_STD_PAL_I, | 162 | .std = V4L2_STD_PAL_I, |
@@ -160,8 +164,10 @@ static struct tvnorm tvnorms[] = { | |||
160 | .b = ( cNegativeFmTV | | 164 | .b = ( cNegativeFmTV | |
161 | cQSS ), | 165 | cQSS ), |
162 | .c = ( cDeemphasisON | | 166 | .c = ( cDeemphasisON | |
163 | cDeemphasis50 ), | 167 | cDeemphasis50 | |
164 | .e = ( cAudioIF_6_0 | | 168 | cTopPalSecamDefault), |
169 | .e = ( cGating_36 | | ||
170 | cAudioIF_6_0 | | ||
165 | cVideoIF_38_90 ), | 171 | cVideoIF_38_90 ), |
166 | },{ | 172 | },{ |
167 | .std = V4L2_STD_PAL_DK, | 173 | .std = V4L2_STD_PAL_DK, |
@@ -169,52 +175,80 @@ static struct tvnorm tvnorms[] = { | |||
169 | .b = ( cNegativeFmTV | | 175 | .b = ( cNegativeFmTV | |
170 | cQSS ), | 176 | cQSS ), |
171 | .c = ( cDeemphasisON | | 177 | .c = ( cDeemphasisON | |
172 | cDeemphasis50 ), | 178 | cDeemphasis50 | |
173 | .e = ( cAudioIF_6_5 | | 179 | cTopPalSecamDefault), |
174 | cVideoIF_38_00 ), | 180 | .e = ( cGating_36 | |
181 | cAudioIF_6_5 | | ||
182 | cVideoIF_38_90 ), | ||
175 | },{ | 183 | },{ |
176 | .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N, | 184 | .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc, |
177 | .name = "PAL-M/N", | 185 | .name = "PAL-M/Nc", |
178 | .b = ( cNegativeFmTV | | 186 | .b = ( cNegativeFmTV | |
179 | cQSS ), | 187 | cQSS ), |
180 | .c = ( cDeemphasisON | | 188 | .c = ( cDeemphasisON | |
181 | cDeemphasis75 ), | 189 | cDeemphasis75 | |
182 | .e = ( cAudioIF_4_5 | | 190 | cTopNtscRadioDefault), |
191 | .e = ( cGating_36 | | ||
192 | cAudioIF_4_5 | | ||
183 | cVideoIF_45_75 ), | 193 | cVideoIF_45_75 ), |
184 | },{ | 194 | },{ |
195 | .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, | ||
196 | .name = "SECAM-BGH", | ||
197 | .b = ( cPositiveAmTV | | ||
198 | cQSS ), | ||
199 | .c = ( cTopPalSecamDefault), | ||
200 | .e = ( cGating_36 | | ||
201 | cAudioIF_5_5 | | ||
202 | cVideoIF_38_90 ), | ||
203 | },{ | ||
185 | .std = V4L2_STD_SECAM_L, | 204 | .std = V4L2_STD_SECAM_L, |
186 | .name = "SECAM-L", | 205 | .name = "SECAM-L", |
187 | .b = ( cPositiveAmTV | | 206 | .b = ( cPositiveAmTV | |
188 | cQSS ), | 207 | cQSS ), |
208 | .c = ( cTopPalSecamDefault), | ||
189 | .e = ( cGating_36 | | 209 | .e = ( cGating_36 | |
190 | cAudioIF_6_5 | | 210 | cAudioIF_6_5 | |
191 | cVideoIF_38_90 ), | 211 | cVideoIF_38_90 ), |
192 | },{ | 212 | },{ |
213 | .std = V4L2_STD_SECAM_LC, | ||
214 | .name = "SECAM-L'", | ||
215 | .b = ( cOutputPort2Inactive | | ||
216 | cPositiveAmTV | | ||
217 | cQSS ), | ||
218 | .c = ( cTopPalSecamDefault), | ||
219 | .e = ( cGating_36 | | ||
220 | cAudioIF_6_5 | | ||
221 | cVideoIF_33_90 ), | ||
222 | },{ | ||
193 | .std = V4L2_STD_SECAM_DK, | 223 | .std = V4L2_STD_SECAM_DK, |
194 | .name = "SECAM-DK", | 224 | .name = "SECAM-DK", |
195 | .b = ( cNegativeFmTV | | 225 | .b = ( cNegativeFmTV | |
196 | cQSS ), | 226 | cQSS ), |
197 | .c = ( cDeemphasisON | | 227 | .c = ( cDeemphasisON | |
198 | cDeemphasis50 ), | 228 | cDeemphasis50 | |
199 | .e = ( cAudioIF_6_5 | | 229 | cTopPalSecamDefault), |
200 | cVideoIF_38_00 ), | 230 | .e = ( cGating_36 | |
231 | cAudioIF_6_5 | | ||
232 | cVideoIF_38_90 ), | ||
201 | },{ | 233 | },{ |
202 | .std = V4L2_STD_NTSC_M, | 234 | .std = V4L2_STD_NTSC_M, |
203 | .name = "NTSC-M", | 235 | .name = "NTSC-M", |
204 | .b = ( cNegativeFmTV | | 236 | .b = ( cNegativeFmTV | |
205 | cQSS ), | 237 | cQSS ), |
206 | .c = ( cDeemphasisON | | 238 | .c = ( cDeemphasisON | |
207 | cDeemphasis75 ), | 239 | cDeemphasis75 | |
240 | cTopNtscRadioDefault), | ||
208 | .e = ( cGating_36 | | 241 | .e = ( cGating_36 | |
209 | cAudioIF_4_5 | | 242 | cAudioIF_4_5 | |
210 | cVideoIF_45_75 ), | 243 | cVideoIF_45_75 ), |
211 | },{ | 244 | },{ |
212 | .std = V4L2_STD_NTSC_M_JP, | 245 | .std = V4L2_STD_NTSC_M_JP, |
213 | .name = "NTSC-JP", | 246 | .name = "NTSC-M-JP", |
214 | .b = ( cNegativeFmTV | | 247 | .b = ( cNegativeFmTV | |
215 | cQSS ), | 248 | cQSS ), |
216 | .c = ( cDeemphasisON | | 249 | .c = ( cDeemphasisON | |
217 | cDeemphasis50 ), | 250 | cDeemphasis50 | |
251 | cTopNtscRadioDefault), | ||
218 | .e = ( cGating_36 | | 252 | .e = ( cGating_36 | |
219 | cAudioIF_4_5 | | 253 | cAudioIF_4_5 | |
220 | cVideoIF_58_75 ), | 254 | cVideoIF_58_75 ), |
@@ -226,8 +260,10 @@ static struct tvnorm radio_stereo = { | |||
226 | .b = ( cFmRadio | | 260 | .b = ( cFmRadio | |
227 | cQSS ), | 261 | cQSS ), |
228 | .c = ( cDeemphasisOFF | | 262 | .c = ( cDeemphasisOFF | |
229 | cAudioGain6 ), | 263 | cAudioGain6 | |
230 | .e = ( cAudioIF_5_5 | | 264 | cTopNtscRadioDefault), |
265 | .e = ( cTunerGainLow | | ||
266 | cAudioIF_5_5 | | ||
231 | cRadioIF_38_90 ), | 267 | cRadioIF_38_90 ), |
232 | }; | 268 | }; |
233 | 269 | ||
@@ -236,8 +272,10 @@ static struct tvnorm radio_mono = { | |||
236 | .b = ( cFmRadio | | 272 | .b = ( cFmRadio | |
237 | cQSS ), | 273 | cQSS ), |
238 | .c = ( cDeemphasisON | | 274 | .c = ( cDeemphasisON | |
239 | cDeemphasis50), | 275 | cDeemphasis75 | |
240 | .e = ( cAudioIF_5_5 | | 276 | cTopNtscRadioDefault), |
277 | .e = ( cTunerGainLow | | ||
278 | cAudioIF_5_5 | | ||
241 | cRadioIF_38_90 ), | 279 | cRadioIF_38_90 ), |
242 | }; | 280 | }; |
243 | 281 | ||
@@ -400,7 +438,8 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) | |||
400 | static unsigned int port1 = UNSET; | 438 | static unsigned int port1 = UNSET; |
401 | static unsigned int port2 = UNSET; | 439 | static unsigned int port2 = UNSET; |
402 | static unsigned int qss = UNSET; | 440 | static unsigned int qss = UNSET; |
403 | static unsigned int adjust = 0x10; | 441 | static unsigned int adjust = UNSET; |
442 | |||
404 | module_param(port1, int, 0644); | 443 | module_param(port1, int, 0644); |
405 | module_param(port2, int, 0644); | 444 | module_param(port2, int, 0644); |
406 | module_param(qss, int, 0644); | 445 | module_param(qss, int, 0644); |
@@ -428,8 +467,10 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf) | |||
428 | buf[1] &= ~cQSS; | 467 | buf[1] &= ~cQSS; |
429 | } | 468 | } |
430 | 469 | ||
431 | if (adjust >= 0x00 && adjust < 0x20) | 470 | if (adjust >= 0x00 && adjust < 0x20) { |
471 | buf[2] &= ~cTopMask; | ||
432 | buf[2] |= adjust; | 472 | buf[2] |= adjust; |
473 | } | ||
433 | return 0; | 474 | return 0; |
434 | } | 475 | } |
435 | 476 | ||
@@ -465,6 +506,10 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) | |||
465 | break; | 506 | break; |
466 | } | 507 | } |
467 | } | 508 | } |
509 | if (t->config & TDA9887_TOP_SET) { | ||
510 | buf[2] &= ~cTopMask; | ||
511 | buf[2] |= (t->config >> 8) & cTopMask; | ||
512 | } | ||
468 | if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) | 513 | if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) |
469 | buf[1] &= ~cQSS; | 514 | buf[1] &= ~cQSS; |
470 | return 0; | 515 | return 0; |
@@ -472,38 +517,13 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) | |||
472 | 517 | ||
473 | /* ---------------------------------------------------------------------- */ | 518 | /* ---------------------------------------------------------------------- */ |
474 | 519 | ||
475 | static int tda9887_set_pinnacle(struct tda9887 *t, char *buf) | 520 | static char pal[] = "--"; |
476 | { | 521 | static char secam[] = "--"; |
477 | unsigned int bCarrierMode = UNSET; | 522 | static char ntsc[] = "-"; |
478 | |||
479 | if (t->std & V4L2_STD_625_50) { | ||
480 | if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) { | ||
481 | bCarrierMode = cIntercarrier; | ||
482 | } else { | ||
483 | bCarrierMode = cQSS; | ||
484 | } | ||
485 | } | ||
486 | if (t->std & V4L2_STD_525_60) { | ||
487 | if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { | ||
488 | bCarrierMode = cIntercarrier; | ||
489 | } else { | ||
490 | bCarrierMode = cQSS; | ||
491 | } | ||
492 | } | ||
493 | |||
494 | if (bCarrierMode != UNSET) { | ||
495 | buf[1] &= ~0x04; | ||
496 | buf[1] |= bCarrierMode; | ||
497 | } | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | /* ---------------------------------------------------------------------- */ | ||
502 | 523 | ||
503 | static char pal[] = "-"; | ||
504 | module_param_string(pal, pal, sizeof(pal), 0644); | 524 | module_param_string(pal, pal, sizeof(pal), 0644); |
505 | static char secam[] = "-"; | ||
506 | module_param_string(secam, secam, sizeof(secam), 0644); | 525 | module_param_string(secam, secam, sizeof(secam), 0644); |
526 | module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); | ||
507 | 527 | ||
508 | static int tda9887_fixup_std(struct tda9887 *t) | 528 | static int tda9887_fixup_std(struct tda9887 *t) |
509 | { | 529 | { |
@@ -514,8 +534,17 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
514 | case 'B': | 534 | case 'B': |
515 | case 'g': | 535 | case 'g': |
516 | case 'G': | 536 | case 'G': |
517 | tda9887_dbg("insmod fixup: PAL => PAL-BG\n"); | 537 | case 'h': |
518 | t->std = V4L2_STD_PAL_BG; | 538 | case 'H': |
539 | case 'n': | ||
540 | case 'N': | ||
541 | if (pal[1] == 'c' || pal[1] == 'C') { | ||
542 | tda9887_dbg("insmod fixup: PAL => PAL-Nc\n"); | ||
543 | t->std = V4L2_STD_PAL_Nc; | ||
544 | } else { | ||
545 | tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n"); | ||
546 | t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N; | ||
547 | } | ||
519 | break; | 548 | break; |
520 | case 'i': | 549 | case 'i': |
521 | case 'I': | 550 | case 'I': |
@@ -529,6 +558,11 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
529 | tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); | 558 | tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); |
530 | t->std = V4L2_STD_PAL_DK; | 559 | t->std = V4L2_STD_PAL_DK; |
531 | break; | 560 | break; |
561 | case 'm': | ||
562 | case 'M': | ||
563 | tda9887_dbg("insmod fixup: PAL => PAL-M\n"); | ||
564 | t->std = V4L2_STD_PAL_M; | ||
565 | break; | ||
532 | case '-': | 566 | case '-': |
533 | /* default parameter, do nothing */ | 567 | /* default parameter, do nothing */ |
534 | break; | 568 | break; |
@@ -539,6 +573,15 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
539 | } | 573 | } |
540 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | 574 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { |
541 | switch (secam[0]) { | 575 | switch (secam[0]) { |
576 | case 'b': | ||
577 | case 'B': | ||
578 | case 'g': | ||
579 | case 'G': | ||
580 | case 'h': | ||
581 | case 'H': | ||
582 | tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n"); | ||
583 | t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; | ||
584 | break; | ||
542 | case 'd': | 585 | case 'd': |
543 | case 'D': | 586 | case 'D': |
544 | case 'k': | 587 | case 'k': |
@@ -548,8 +591,13 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
548 | break; | 591 | break; |
549 | case 'l': | 592 | case 'l': |
550 | case 'L': | 593 | case 'L': |
551 | tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); | 594 | if (secam[1] == 'c' || secam[1] == 'C') { |
552 | t->std = V4L2_STD_SECAM_L; | 595 | tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n"); |
596 | t->std = V4L2_STD_SECAM_LC; | ||
597 | } else { | ||
598 | tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); | ||
599 | t->std = V4L2_STD_SECAM_L; | ||
600 | } | ||
553 | break; | 601 | break; |
554 | case '-': | 602 | case '-': |
555 | /* default parameter, do nothing */ | 603 | /* default parameter, do nothing */ |
@@ -559,6 +607,26 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
559 | break; | 607 | break; |
560 | } | 608 | } |
561 | } | 609 | } |
610 | if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | ||
611 | switch (ntsc[0]) { | ||
612 | case 'm': | ||
613 | case 'M': | ||
614 | tda9887_dbg("insmod fixup: NTSC => NTSC-M\n"); | ||
615 | t->std = V4L2_STD_NTSC_M; | ||
616 | break; | ||
617 | case 'j': | ||
618 | case 'J': | ||
619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | ||
620 | t->std = V4L2_STD_NTSC_M_JP; | ||
621 | break; | ||
622 | case '-': | ||
623 | /* default parameter, do nothing */ | ||
624 | break; | ||
625 | default: | ||
626 | tda9887_info("ntsc= argument not recognised\n"); | ||
627 | break; | ||
628 | } | ||
629 | } | ||
562 | return 0; | 630 | return 0; |
563 | } | 631 | } |
564 | 632 | ||
@@ -581,12 +649,22 @@ static int tda9887_configure(struct tda9887 *t) | |||
581 | memset(t->data,0,sizeof(t->data)); | 649 | memset(t->data,0,sizeof(t->data)); |
582 | tda9887_set_tvnorm(t,t->data); | 650 | tda9887_set_tvnorm(t,t->data); |
583 | 651 | ||
652 | /* A note on the port settings: | ||
653 | These settings tend to depend on the specifics of the board. | ||
654 | By default they are set to inactive (bit value 1) by this driver, | ||
655 | overwriting any changes made by the tvnorm. This means that it | ||
656 | is the responsibility of the module using the tda9887 to set | ||
657 | these values in case of changes in the tvnorm. | ||
658 | In many cases port 2 should be made active (0) when selecting | ||
659 | SECAM-L, and port 2 should remain inactive (1) for SECAM-L'. | ||
660 | |||
661 | For the other standards the tda9887 application note says that | ||
662 | the ports should be set to active (0), but, again, that may | ||
663 | differ depending on the precise hardware configuration. | ||
664 | */ | ||
584 | t->data[1] |= cOutputPort1Inactive; | 665 | t->data[1] |= cOutputPort1Inactive; |
585 | t->data[1] |= cOutputPort2Inactive; | 666 | t->data[1] |= cOutputPort2Inactive; |
586 | 667 | ||
587 | if (UNSET != t->pinnacle_id) { | ||
588 | tda9887_set_pinnacle(t,t->data); | ||
589 | } | ||
590 | tda9887_set_config(t,t->data); | 668 | tda9887_set_config(t,t->data); |
591 | tda9887_set_insmod(t,t->data); | 669 | tda9887_set_insmod(t,t->data); |
592 | 670 | ||
@@ -594,7 +672,6 @@ static int tda9887_configure(struct tda9887 *t) | |||
594 | t->data[1] |= cForcedMuteAudioON; | 672 | t->data[1] |= cForcedMuteAudioON; |
595 | } | 673 | } |
596 | 674 | ||
597 | |||
598 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", | 675 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", |
599 | t->data[1],t->data[2],t->data[3]); | 676 | t->data[1],t->data[2],t->data[3]); |
600 | if (debug > 1) | 677 | if (debug > 1) |
@@ -625,7 +702,6 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | |||
625 | 702 | ||
626 | t->client = client_template; | 703 | t->client = client_template; |
627 | t->std = 0; | 704 | t->std = 0; |
628 | t->pinnacle_id = UNSET; | ||
629 | t->radio_mode = V4L2_TUNER_MODE_STEREO; | 705 | t->radio_mode = V4L2_TUNER_MODE_STEREO; |
630 | 706 | ||
631 | tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); | 707 | tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); |
@@ -638,18 +714,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | |||
638 | 714 | ||
639 | static int tda9887_probe(struct i2c_adapter *adap) | 715 | static int tda9887_probe(struct i2c_adapter *adap) |
640 | { | 716 | { |
641 | #ifdef I2C_CLASS_TV_ANALOG | ||
642 | if (adap->class & I2C_CLASS_TV_ANALOG) | 717 | if (adap->class & I2C_CLASS_TV_ANALOG) |
643 | return i2c_probe(adap, &addr_data, tda9887_attach); | 718 | return i2c_probe(adap, &addr_data, tda9887_attach); |
644 | #else | ||
645 | switch (adap->id) { | ||
646 | case I2C_HW_B_BT848: | ||
647 | case I2C_HW_B_RIVA: | ||
648 | case I2C_HW_SAA7134: | ||
649 | return i2c_probe(adap, &addr_data, tda9887_attach); | ||
650 | break; | ||
651 | } | ||
652 | #endif | ||
653 | return 0; | 719 | return 0; |
654 | } | 720 | } |
655 | 721 | ||
@@ -689,14 +755,6 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
689 | tda9887_configure(t); | 755 | tda9887_configure(t); |
690 | break; | 756 | break; |
691 | } | 757 | } |
692 | case AUDC_CONFIG_PINNACLE: | ||
693 | { | ||
694 | int *i = arg; | ||
695 | |||
696 | t->pinnacle_id = *i; | ||
697 | tda9887_configure(t); | ||
698 | break; | ||
699 | } | ||
700 | case TDA9887_SET_CONFIG: | 758 | case TDA9887_SET_CONFIG: |
701 | { | 759 | { |
702 | int *i = arg; | 760 | int *i = arg; |
@@ -787,7 +845,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
787 | } | 845 | } |
788 | case VIDIOC_LOG_STATUS: | 846 | case VIDIOC_LOG_STATUS: |
789 | { | 847 | { |
790 | tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]); | 848 | tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]); |
791 | break; | 849 | break; |
792 | } | 850 | } |
793 | default: | 851 | default: |
@@ -824,7 +882,7 @@ static struct i2c_driver driver = { | |||
824 | .detach_client = tda9887_detach, | 882 | .detach_client = tda9887_detach, |
825 | .command = tda9887_command, | 883 | .command = tda9887_command, |
826 | .driver = { | 884 | .driver = { |
827 | .name = "i2c tda9887 driver", | 885 | .name = "tda9887", |
828 | .suspend = tda9887_suspend, | 886 | .suspend = tda9887_suspend, |
829 | .resume = tda9887_resume, | 887 | .resume = tda9887_resume, |
830 | }, | 888 | }, |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index a9375ef05de1..261b7a3c0417 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -17,6 +17,9 @@ | |||
17 | 17 | ||
18 | #define PREFIX "TEA5767 " | 18 | #define PREFIX "TEA5767 " |
19 | 19 | ||
20 | /* from tuner-core.c */ | ||
21 | extern int debug; | ||
22 | |||
20 | /*****************************************************************************/ | 23 | /*****************************************************************************/ |
21 | 24 | ||
22 | /****************************** | 25 | /****************************** |
@@ -246,7 +249,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq) | |||
246 | if (5 != (rc = i2c_master_send(c, buffer, 5))) | 249 | if (5 != (rc = i2c_master_send(c, buffer, 5))) |
247 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | 250 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); |
248 | 251 | ||
249 | if (tuner_debug) { | 252 | if (debug) { |
250 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) | 253 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) |
251 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | 254 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); |
252 | else | 255 | else |
@@ -264,7 +267,7 @@ static int tea5767_signal(struct i2c_client *c) | |||
264 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) | 267 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) |
265 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | 268 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); |
266 | 269 | ||
267 | return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4)); | 270 | return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8); |
268 | } | 271 | } |
269 | 272 | ||
270 | static int tea5767_stereo(struct i2c_client *c) | 273 | static int tea5767_stereo(struct i2c_client *c) |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index c13c7b95ef35..57bc585a6955 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -20,10 +20,9 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | 21 | ||
22 | #include <media/tuner.h> | 22 | #include <media/tuner.h> |
23 | #include <media/v4l2-common.h> | ||
23 | #include <media/audiochip.h> | 24 | #include <media/audiochip.h> |
24 | 25 | ||
25 | #include "msp3400.h" | ||
26 | |||
27 | #define UNSET (-1U) | 26 | #define UNSET (-1U) |
28 | 27 | ||
29 | /* standard i2c insmod options */ | 28 | /* standard i2c insmod options */ |
@@ -38,21 +37,30 @@ I2C_CLIENT_INSMOD; | |||
38 | 37 | ||
39 | /* insmod options used at init time => read/only */ | 38 | /* insmod options used at init time => read/only */ |
40 | static unsigned int addr = 0; | 39 | static unsigned int addr = 0; |
41 | module_param(addr, int, 0444); | ||
42 | |||
43 | static unsigned int no_autodetect = 0; | 40 | static unsigned int no_autodetect = 0; |
44 | module_param(no_autodetect, int, 0444); | ||
45 | |||
46 | static unsigned int show_i2c = 0; | 41 | static unsigned int show_i2c = 0; |
47 | module_param(show_i2c, int, 0444); | ||
48 | 42 | ||
49 | /* insmod options used at runtime => read/write */ | 43 | /* insmod options used at runtime => read/write */ |
50 | unsigned int tuner_debug = 0; | 44 | static unsigned int tuner_debug = 0; |
51 | module_param(tuner_debug, int, 0644); | 45 | int debug = 0; |
52 | 46 | ||
53 | static unsigned int tv_range[2] = { 44, 958 }; | 47 | static unsigned int tv_range[2] = { 44, 958 }; |
54 | static unsigned int radio_range[2] = { 65, 108 }; | 48 | static unsigned int radio_range[2] = { 65, 108 }; |
55 | 49 | ||
50 | static char pal[] = "--"; | ||
51 | static char secam[] = "--"; | ||
52 | static char ntsc[] = "-"; | ||
53 | |||
54 | module_param(addr, int, 0444); | ||
55 | module_param(no_autodetect, int, 0444); | ||
56 | module_param(show_i2c, int, 0444); | ||
57 | /* Note: tuner_debug is deprecated and will be removed in 2.6.17 */ | ||
58 | module_param(tuner_debug, int, 0444); | ||
59 | module_param(debug, int, 0644); | ||
60 | |||
61 | module_param_string(pal, pal, sizeof(pal), 0644); | ||
62 | module_param_string(secam, secam, sizeof(secam), 0644); | ||
63 | module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); | ||
56 | module_param_array(tv_range, int, NULL, 0644); | 64 | module_param_array(tv_range, int, NULL, 0644); |
57 | module_param_array(radio_range, int, NULL, 0644); | 65 | module_param_array(radio_range, int, NULL, 0644); |
58 | 66 | ||
@@ -249,11 +257,6 @@ static inline int check_mode(struct tuner *t, char *cmd) | |||
249 | return 0; | 257 | return 0; |
250 | } | 258 | } |
251 | 259 | ||
252 | static char pal[] = "-"; | ||
253 | module_param_string(pal, pal, sizeof(pal), 0644); | ||
254 | static char secam[] = "--"; | ||
255 | module_param_string(secam, secam, sizeof(secam), 0644); | ||
256 | |||
257 | /* get more precise norm info from insmod option */ | 260 | /* get more precise norm info from insmod option */ |
258 | static int tuner_fixup_std(struct tuner *t) | 261 | static int tuner_fixup_std(struct tuner *t) |
259 | { | 262 | { |
@@ -285,8 +288,13 @@ static int tuner_fixup_std(struct tuner *t) | |||
285 | break; | 288 | break; |
286 | case 'N': | 289 | case 'N': |
287 | case 'n': | 290 | case 'n': |
288 | tuner_dbg ("insmod fixup: PAL => PAL-N\n"); | 291 | if (pal[1] == 'c' || pal[1] == 'C') { |
289 | t->std = V4L2_STD_PAL_N; | 292 | tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); |
293 | t->std = V4L2_STD_PAL_Nc; | ||
294 | } else { | ||
295 | tuner_dbg ("insmod fixup: PAL => PAL-N\n"); | ||
296 | t->std = V4L2_STD_PAL_N; | ||
297 | } | ||
290 | break; | 298 | break; |
291 | case '-': | 299 | case '-': |
292 | /* default parameter, do nothing */ | 300 | /* default parameter, do nothing */ |
@@ -298,6 +306,15 @@ static int tuner_fixup_std(struct tuner *t) | |||
298 | } | 306 | } |
299 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | 307 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { |
300 | switch (secam[0]) { | 308 | switch (secam[0]) { |
309 | case 'b': | ||
310 | case 'B': | ||
311 | case 'g': | ||
312 | case 'G': | ||
313 | case 'h': | ||
314 | case 'H': | ||
315 | tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); | ||
316 | t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; | ||
317 | break; | ||
301 | case 'd': | 318 | case 'd': |
302 | case 'D': | 319 | case 'D': |
303 | case 'k': | 320 | case 'k': |
@@ -324,9 +341,60 @@ static int tuner_fixup_std(struct tuner *t) | |||
324 | } | 341 | } |
325 | } | 342 | } |
326 | 343 | ||
344 | if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | ||
345 | switch (ntsc[0]) { | ||
346 | case 'm': | ||
347 | case 'M': | ||
348 | tuner_dbg("insmod fixup: NTSC => NTSC-M\n"); | ||
349 | t->std = V4L2_STD_NTSC_M; | ||
350 | break; | ||
351 | case 'j': | ||
352 | case 'J': | ||
353 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | ||
354 | t->std = V4L2_STD_NTSC_M_JP; | ||
355 | break; | ||
356 | case '-': | ||
357 | /* default parameter, do nothing */ | ||
358 | break; | ||
359 | default: | ||
360 | tuner_info("ntsc= argument not recognised\n"); | ||
361 | break; | ||
362 | } | ||
363 | } | ||
327 | return 0; | 364 | return 0; |
328 | } | 365 | } |
329 | 366 | ||
367 | static void tuner_status(struct i2c_client *client) | ||
368 | { | ||
369 | struct tuner *t = i2c_get_clientdata(client); | ||
370 | unsigned long freq, freq_fraction; | ||
371 | const char *p; | ||
372 | |||
373 | switch (t->mode) { | ||
374 | case V4L2_TUNER_RADIO: p = "radio"; break; | ||
375 | case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break; | ||
376 | case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break; | ||
377 | default: p = "undefined"; break; | ||
378 | } | ||
379 | if (t->mode == V4L2_TUNER_RADIO) { | ||
380 | freq = t->freq / 16000; | ||
381 | freq_fraction = (t->freq % 16000) * 100 / 16000; | ||
382 | } else { | ||
383 | freq = t->freq / 16; | ||
384 | freq_fraction = (t->freq % 16) * 100 / 16; | ||
385 | } | ||
386 | tuner_info("Tuner mode: %s\n", p); | ||
387 | tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); | ||
388 | tuner_info("Standard: 0x%08llx\n", t->std); | ||
389 | if (t->mode == V4L2_TUNER_RADIO) { | ||
390 | if (t->has_signal) { | ||
391 | tuner_info("Signal strength: %d\n", t->has_signal(client)); | ||
392 | } | ||
393 | if (t->is_stereo) { | ||
394 | tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); | ||
395 | } | ||
396 | } | ||
397 | } | ||
330 | /* ---------------------------------------------------------------------- */ | 398 | /* ---------------------------------------------------------------------- */ |
331 | 399 | ||
332 | /* static var Used only in tuner_attach and tuner_probe */ | 400 | /* static var Used only in tuner_attach and tuner_probe */ |
@@ -352,6 +420,11 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
352 | t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | 420 | t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ |
353 | t->audmode = V4L2_TUNER_MODE_STEREO; | 421 | t->audmode = V4L2_TUNER_MODE_STEREO; |
354 | t->mode_mask = T_UNINITIALIZED; | 422 | t->mode_mask = T_UNINITIALIZED; |
423 | if (tuner_debug) { | ||
424 | debug = tuner_debug; | ||
425 | printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); | ||
426 | printk(KERN_ERR "tuner: use the debug option instead.\n"); | ||
427 | } | ||
355 | 428 | ||
356 | if (show_i2c) { | 429 | if (show_i2c) { |
357 | unsigned char buffer[16]; | 430 | unsigned char buffer[16]; |
@@ -478,7 +551,9 @@ static inline int check_v4l2(struct tuner *t) | |||
478 | static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | 551 | static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) |
479 | { | 552 | { |
480 | struct tuner *t = i2c_get_clientdata(client); | 553 | struct tuner *t = i2c_get_clientdata(client); |
481 | unsigned int *iarg = (int *)arg; | 554 | |
555 | if (debug>1) | ||
556 | v4l_i2c_print_ioctl(&(t->i2c),cmd); | ||
482 | 557 | ||
483 | switch (cmd) { | 558 | switch (cmd) { |
484 | /* --- configuration --- */ | 559 | /* --- configuration --- */ |
@@ -501,18 +576,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
501 | t->standby (client); | 576 | t->standby (client); |
502 | break; | 577 | break; |
503 | } | 578 | } |
504 | case AUDC_CONFIG_PINNACLE: | ||
505 | switch (*iarg) { | ||
506 | case 2: | ||
507 | tuner_dbg("pinnacle pal\n"); | ||
508 | t->radio_if2 = 33300 * 1000; | ||
509 | break; | ||
510 | case 3: | ||
511 | tuner_dbg("pinnacle ntsc\n"); | ||
512 | t->radio_if2 = 41300 * 1000; | ||
513 | break; | ||
514 | } | ||
515 | break; | ||
516 | case VIDIOCSAUDIO: | 579 | case VIDIOCSAUDIO: |
517 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) | 580 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) |
518 | return 0; | 581 | return 0; |
@@ -523,9 +586,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
523 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); | 586 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); |
524 | 587 | ||
525 | break; | 588 | break; |
526 | case MSP_SET_MATRIX: | ||
527 | case TDA9887_SET_CONFIG: | ||
528 | break; | ||
529 | /* --- v4l ioctls --- */ | 589 | /* --- v4l ioctls --- */ |
530 | /* take care: bttv does userspace copying, we'll get a | 590 | /* take care: bttv does userspace copying, we'll get a |
531 | kernel pointer here... */ | 591 | kernel pointer here... */ |
@@ -708,10 +768,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
708 | } | 768 | } |
709 | break; | 769 | break; |
710 | } | 770 | } |
711 | default: | 771 | case VIDIOC_LOG_STATUS: |
712 | tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n", | 772 | tuner_status(client); |
713 | cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), | ||
714 | _IOC_NR(cmd), _IOC_SIZE(cmd)); | ||
715 | break; | 773 | break; |
716 | } | 774 | } |
717 | 775 | ||
@@ -747,10 +805,10 @@ static struct i2c_driver driver = { | |||
747 | .detach_client = tuner_detach, | 805 | .detach_client = tuner_detach, |
748 | .command = tuner_command, | 806 | .command = tuner_command, |
749 | .driver = { | 807 | .driver = { |
750 | .name = "tuner", | 808 | .name = "tuner", |
751 | .suspend = tuner_suspend, | 809 | .suspend = tuner_suspend, |
752 | .resume = tuner_resume, | 810 | .resume = tuner_resume, |
753 | }, | 811 | }, |
754 | }; | 812 | }; |
755 | static struct i2c_client client_template = { | 813 | static struct i2c_client client_template = { |
756 | .name = "(tuner unset)", | 814 | .name = "(tuner unset)", |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index e0c9fdb9914a..e5fb74365836 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -8,6 +8,10 @@ | |||
8 | #include <linux/videodev.h> | 8 | #include <linux/videodev.h> |
9 | #include <media/tuner.h> | 9 | #include <media/tuner.h> |
10 | 10 | ||
11 | static int offset = 0; | ||
12 | module_param(offset, int, 0666); | ||
13 | MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | ||
14 | |||
11 | /* ---------------------------------------------------------------------- */ | 15 | /* ---------------------------------------------------------------------- */ |
12 | 16 | ||
13 | /* tv standard selection for Temic 4046 FM5 | 17 | /* tv standard selection for Temic 4046 FM5 |
@@ -75,24 +79,20 @@ | |||
75 | #define TUNER_PLL_LOCKED 0x40 | 79 | #define TUNER_PLL_LOCKED 0x40 |
76 | #define TUNER_STEREO_MK3 0x04 | 80 | #define TUNER_STEREO_MK3 0x04 |
77 | 81 | ||
82 | #define TUNER_MAX_RANGES 3 | ||
83 | |||
78 | /* ---------------------------------------------------------------------- */ | 84 | /* ---------------------------------------------------------------------- */ |
79 | 85 | ||
80 | struct tunertype | 86 | struct tunertype |
81 | { | 87 | { |
82 | char *name; | 88 | char *name; |
83 | unsigned char Vendor; | 89 | |
84 | unsigned char Type; | 90 | int count; |
85 | 91 | struct { | |
86 | unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */ | 92 | unsigned short thresh; |
87 | unsigned short thresh2; /* band switch VHF_HI <=> UHF */ | 93 | unsigned char cb; |
88 | unsigned char VHF_L; | 94 | } ranges[TUNER_MAX_RANGES]; |
89 | unsigned char VHF_H; | ||
90 | unsigned char UHF; | ||
91 | unsigned char config; | 95 | unsigned char config; |
92 | unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, | ||
93 | 732 =16*45.75 NTSCi, | ||
94 | 940 =16*58.75 NTSC-Japan | ||
95 | 704 =16*44 ATSC */ | ||
96 | }; | 96 | }; |
97 | 97 | ||
98 | /* | 98 | /* |
@@ -102,158 +102,696 @@ struct tunertype | |||
102 | */ | 102 | */ |
103 | static struct tunertype tuners[] = { | 103 | static struct tunertype tuners[] = { |
104 | /* 0-9 */ | 104 | /* 0-9 */ |
105 | { "Temic PAL (4002 FH5)", TEMIC, PAL, | 105 | [TUNER_TEMIC_PAL] = { /* TEMIC PAL */ |
106 | 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, | 106 | .name = "Temic PAL (4002 FH5)", |
107 | { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, | 107 | .count = 3, |
108 | 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | 108 | .ranges = { |
109 | { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC, | 109 | { 16 * 140.25 /*MHz*/, 0x02, }, |
110 | 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732}, | 110 | { 16 * 463.25 /*MHz*/, 0x04, }, |
111 | { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM, | 111 | { 16 * 999.99 , 0x01, }, |
112 | 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623}, | 112 | }, |
113 | { "NoTuner", NoTuner, NOTUNER, | 113 | .config = 0x8e, |
114 | 0,0,0x00,0x00,0x00,0x00,0x00}, | 114 | }, |
115 | { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL, | 115 | [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */ |
116 | 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623}, | 116 | .name = "Philips PAL_I (FI1246 and compatibles)", |
117 | { "Temic NTSC (4032 FY5)", TEMIC, NTSC, | 117 | .count = 3, |
118 | 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, | 118 | .ranges = { |
119 | { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, | 119 | { 16 * 140.25 /*MHz*/, 0xa0, }, |
120 | 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, | 120 | { 16 * 463.25 /*MHz*/, 0x90, }, |
121 | { "Temic NTSC (4036 FY5)", TEMIC, NTSC, | 121 | { 16 * 999.99 , 0x30, }, |
122 | 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, | 122 | }, |
123 | { "Alps HSBH1", TEMIC, NTSC, | 123 | .config = 0x8e, |
124 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | 124 | }, |
125 | [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */ | ||
126 | .name = "Philips NTSC (FI1236,FM1236 and compatibles)", | ||
127 | .count = 3, | ||
128 | .ranges = { | ||
129 | { 16 * 157.25 /*MHz*/, 0xa0, }, | ||
130 | { 16 * 451.25 /*MHz*/, 0x90, }, | ||
131 | { 16 * 999.99 , 0x30, }, | ||
132 | }, | ||
133 | .config = 0x8e, | ||
134 | }, | ||
135 | [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */ | ||
136 | .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", | ||
137 | .count = 3, | ||
138 | .ranges = { | ||
139 | { 16 * 168.25 /*MHz*/, 0xa7, }, | ||
140 | { 16 * 447.25 /*MHz*/, 0x97, }, | ||
141 | { 16 * 999.99 , 0x37, }, | ||
142 | }, | ||
143 | .config = 0x8e, | ||
144 | }, | ||
145 | [TUNER_ABSENT] = { /* Tuner Absent */ | ||
146 | .name = "NoTuner", | ||
147 | .count = 1, | ||
148 | .ranges = { | ||
149 | { 0, 0x00, }, | ||
150 | }, | ||
151 | .config = 0x00, | ||
152 | }, | ||
153 | [TUNER_PHILIPS_PAL] = { /* Philips PAL */ | ||
154 | .name = "Philips PAL_BG (FI1216 and compatibles)", | ||
155 | .count = 3, | ||
156 | .ranges = { | ||
157 | { 16 * 168.25 /*MHz*/, 0xa0, }, | ||
158 | { 16 * 447.25 /*MHz*/, 0x90, }, | ||
159 | { 16 * 999.99 , 0x30, }, | ||
160 | }, | ||
161 | .config = 0x8e, | ||
162 | }, | ||
163 | [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */ | ||
164 | .name = "Temic NTSC (4032 FY5)", | ||
165 | .count = 3, | ||
166 | .ranges = { | ||
167 | { 16 * 157.25 /*MHz*/, 0x02, }, | ||
168 | { 16 * 463.25 /*MHz*/, 0x04, }, | ||
169 | { 16 * 999.99 , 0x01, }, | ||
170 | }, | ||
171 | .config = 0x8e, | ||
172 | }, | ||
173 | [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */ | ||
174 | .name = "Temic PAL_I (4062 FY5)", | ||
175 | .count = 3, | ||
176 | .ranges = { | ||
177 | { 16 * 170.00 /*MHz*/, 0x02, }, | ||
178 | { 16 * 450.00 /*MHz*/, 0x04, }, | ||
179 | { 16 * 999.99 , 0x01, }, | ||
180 | }, | ||
181 | .config = 0x8e, | ||
182 | }, | ||
183 | [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */ | ||
184 | .name = "Temic NTSC (4036 FY5)", | ||
185 | .count = 3, | ||
186 | .ranges = { | ||
187 | { 16 * 157.25 /*MHz*/, 0xa0, }, | ||
188 | { 16 * 463.25 /*MHz*/, 0x90, }, | ||
189 | { 16 * 999.99 , 0x30, }, | ||
190 | }, | ||
191 | .config = 0x8e, | ||
192 | }, | ||
193 | [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */ | ||
194 | .name = "Alps HSBH1", | ||
195 | .count = 3, | ||
196 | .ranges = { | ||
197 | { 16 * 137.25 /*MHz*/, 0x01, }, | ||
198 | { 16 * 385.25 /*MHz*/, 0x02, }, | ||
199 | { 16 * 999.99 , 0x08, }, | ||
200 | }, | ||
201 | .config = 0x8e, | ||
202 | }, | ||
125 | 203 | ||
126 | /* 10-19 */ | 204 | /* 10-19 */ |
127 | { "Alps TSBE1", TEMIC, PAL, | 205 | [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */ |
128 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | 206 | .name = "Alps TSBE1", |
129 | { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ | 207 | .count = 3, |
130 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, | 208 | .ranges = { |
131 | { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | 209 | { 16 * 137.25 /*MHz*/, 0x01, }, |
132 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, | 210 | { 16 * 385.25 /*MHz*/, 0x02, }, |
133 | { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | 211 | { 16 * 999.99 , 0x08, }, |
134 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, | 212 | }, |
135 | { "Temic PAL_BG (4006FH5)", TEMIC, PAL, | 213 | .config = 0x8e, |
136 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 214 | }, |
137 | { "Alps TSCH6", Alps, NTSC, | 215 | [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */ |
138 | 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, | 216 | .name = "Alps TSBB5", |
139 | { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, | 217 | .count = 3, |
140 | 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, | 218 | .ranges = { |
141 | { "Philips NTSC_M (MK2)", Philips, NTSC, | 219 | { 16 * 133.25 /*MHz*/, 0x01, }, |
142 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, | 220 | { 16 * 351.25 /*MHz*/, 0x02, }, |
143 | { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, | 221 | { 16 * 999.99 , 0x08, }, |
144 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | 222 | }, |
145 | { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, | 223 | .config = 0x8e, |
146 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | 224 | }, |
225 | [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */ | ||
226 | .name = "Alps TSBE5", | ||
227 | .count = 3, | ||
228 | .ranges = { | ||
229 | { 16 * 133.25 /*MHz*/, 0x01, }, | ||
230 | { 16 * 351.25 /*MHz*/, 0x02, }, | ||
231 | { 16 * 999.99 , 0x08, }, | ||
232 | }, | ||
233 | .config = 0x8e, | ||
234 | }, | ||
235 | [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */ | ||
236 | .name = "Alps TSBC5", | ||
237 | .count = 3, | ||
238 | .ranges = { | ||
239 | { 16 * 133.25 /*MHz*/, 0x01, }, | ||
240 | { 16 * 351.25 /*MHz*/, 0x02, }, | ||
241 | { 16 * 999.99 , 0x08, }, | ||
242 | }, | ||
243 | .config = 0x8e, | ||
244 | }, | ||
245 | [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */ | ||
246 | .name = "Temic PAL_BG (4006FH5)", | ||
247 | .count = 3, | ||
248 | .ranges = { | ||
249 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
250 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
251 | { 16 * 999.99 , 0x30, }, | ||
252 | }, | ||
253 | .config = 0x8e, | ||
254 | }, | ||
255 | [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */ | ||
256 | .name = "Alps TSCH6", | ||
257 | .count = 3, | ||
258 | .ranges = { | ||
259 | { 16 * 137.25 /*MHz*/, 0x14, }, | ||
260 | { 16 * 385.25 /*MHz*/, 0x12, }, | ||
261 | { 16 * 999.99 , 0x11, }, | ||
262 | }, | ||
263 | .config = 0x8e, | ||
264 | }, | ||
265 | [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */ | ||
266 | .name = "Temic PAL_DK (4016 FY5)", | ||
267 | .count = 3, | ||
268 | .ranges = { | ||
269 | { 16 * 168.25 /*MHz*/, 0xa0, }, | ||
270 | { 16 * 456.25 /*MHz*/, 0x90, }, | ||
271 | { 16 * 999.99 , 0x30, }, | ||
272 | }, | ||
273 | .config = 0x8e, | ||
274 | }, | ||
275 | [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */ | ||
276 | .name = "Philips NTSC_M (MK2)", | ||
277 | .count = 3, | ||
278 | .ranges = { | ||
279 | { 16 * 160.00 /*MHz*/, 0xa0, }, | ||
280 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
281 | { 16 * 999.99 , 0x30, }, | ||
282 | }, | ||
283 | .config = 0x8e, | ||
284 | }, | ||
285 | [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */ | ||
286 | .name = "Temic PAL_I (4066 FY5)", | ||
287 | .count = 3, | ||
288 | .ranges = { | ||
289 | { 16 * 169.00 /*MHz*/, 0xa0, }, | ||
290 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
291 | { 16 * 999.99 , 0x30, }, | ||
292 | }, | ||
293 | .config = 0x8e, | ||
294 | }, | ||
295 | [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */ | ||
296 | .name = "Temic PAL* auto (4006 FN5)", | ||
297 | .count = 3, | ||
298 | .ranges = { | ||
299 | { 16 * 169.00 /*MHz*/, 0xa0, }, | ||
300 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
301 | { 16 * 999.99 , 0x30, }, | ||
302 | }, | ||
303 | .config = 0x8e, | ||
304 | }, | ||
147 | 305 | ||
148 | /* 20-29 */ | 306 | /* 20-29 */ |
149 | { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, | 307 | [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */ |
150 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | 308 | .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", |
151 | { "Temic NTSC (4039 FR5)", TEMIC, NTSC, | 309 | .count = 3, |
152 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | 310 | .ranges = { |
153 | { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, | 311 | { 16 * 141.00 /*MHz*/, 0xa0, }, |
154 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | 312 | { 16 * 464.00 /*MHz*/, 0x90, }, |
155 | { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, | 313 | { 16 * 999.99 , 0x30, }, |
156 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 314 | }, |
157 | { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, | 315 | .config = 0x8e, |
158 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 316 | }, |
159 | { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I, | 317 | [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */ |
160 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 318 | .name = "Temic NTSC (4039 FR5)", |
161 | { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I, | 319 | .count = 3, |
162 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 320 | .ranges = { |
163 | { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC, | 321 | { 16 * 158.00 /*MHz*/, 0xa0, }, |
164 | 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732}, | 322 | { 16 * 453.00 /*MHz*/, 0x90, }, |
165 | { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL, | 323 | { 16 * 999.99 , 0x30, }, |
166 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 324 | }, |
167 | { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL, | 325 | .config = 0x8e, |
168 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 326 | }, |
327 | [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */ | ||
328 | .name = "Temic PAL/SECAM multi (4046 FM5)", | ||
329 | .count = 3, | ||
330 | .ranges = { | ||
331 | { 16 * 169.00 /*MHz*/, 0xa0, }, | ||
332 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
333 | { 16 * 999.99 , 0x30, }, | ||
334 | }, | ||
335 | .config = 0x8e, | ||
336 | }, | ||
337 | [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */ | ||
338 | .name = "Philips PAL_DK (FI1256 and compatibles)", | ||
339 | .count = 3, | ||
340 | .ranges = { | ||
341 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
342 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
343 | { 16 * 999.99 , 0x30, }, | ||
344 | }, | ||
345 | .config = 0x8e, | ||
346 | }, | ||
347 | [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */ | ||
348 | .name = "Philips PAL/SECAM multi (FQ1216ME)", | ||
349 | .count = 3, | ||
350 | .ranges = { | ||
351 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
352 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
353 | { 16 * 999.99 , 0x30, }, | ||
354 | }, | ||
355 | .config = 0x8e, | ||
356 | }, | ||
357 | [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */ | ||
358 | .name = "LG PAL_I+FM (TAPC-I001D)", | ||
359 | .count = 3, | ||
360 | .ranges = { | ||
361 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
362 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
363 | { 16 * 999.99 , 0x30, }, | ||
364 | }, | ||
365 | .config = 0x8e, | ||
366 | }, | ||
367 | [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */ | ||
368 | .name = "LG PAL_I (TAPC-I701D)", | ||
369 | .count = 3, | ||
370 | .ranges = { | ||
371 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
372 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
373 | { 16 * 999.99 , 0x30, }, | ||
374 | }, | ||
375 | .config = 0x8e, | ||
376 | }, | ||
377 | [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */ | ||
378 | .name = "LG NTSC+FM (TPI8NSR01F)", | ||
379 | .count = 3, | ||
380 | .ranges = { | ||
381 | { 16 * 210.00 /*MHz*/, 0xa0, }, | ||
382 | { 16 * 497.00 /*MHz*/, 0x90, }, | ||
383 | { 16 * 999.99 , 0x30, }, | ||
384 | }, | ||
385 | .config = 0x8e, | ||
386 | }, | ||
387 | [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */ | ||
388 | .name = "LG PAL_BG+FM (TPI8PSB01D)", | ||
389 | .count = 3, | ||
390 | .ranges = { | ||
391 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
392 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
393 | { 16 * 999.99 , 0x30, }, | ||
394 | }, | ||
395 | .config = 0x8e, | ||
396 | }, | ||
397 | [TUNER_LG_PAL] = { /* LGINNOTEK PAL */ | ||
398 | .name = "LG PAL_BG (TPI8PSB11D)", | ||
399 | .count = 3, | ||
400 | .ranges = { | ||
401 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
402 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
403 | { 16 * 999.99 , 0x30, }, | ||
404 | }, | ||
405 | .config = 0x8e, | ||
406 | }, | ||
169 | 407 | ||
170 | /* 30-39 */ | 408 | /* 30-39 */ |
171 | { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL, | 409 | [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */ |
172 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | 410 | .name = "Temic PAL* auto + FM (4009 FN5)", |
173 | { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ | 411 | .count = 3, |
174 | 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, | 412 | .ranges = { |
175 | { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ | 413 | { 16 * 141.00 /*MHz*/, 0xa0, }, |
176 | 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, | 414 | { 16 * 464.00 /*MHz*/, 0x90, }, |
177 | { "MT20xx universal", Microtune, PAL|NTSC, | 415 | { 16 * 999.99 , 0x30, }, |
416 | }, | ||
417 | .config = 0x8e, | ||
418 | }, | ||
419 | [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */ | ||
420 | .name = "SHARP NTSC_JP (2U5JF5540)", | ||
421 | .count = 3, | ||
422 | .ranges = { | ||
423 | { 16 * 137.25 /*MHz*/, 0x01, }, | ||
424 | { 16 * 317.25 /*MHz*/, 0x02, }, | ||
425 | { 16 * 999.99 , 0x08, }, | ||
426 | }, | ||
427 | .config = 0x8e, | ||
428 | }, | ||
429 | [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */ | ||
430 | .name = "Samsung PAL TCPM9091PD27", | ||
431 | .count = 3, | ||
432 | .ranges = { | ||
433 | { 16 * 169 /*MHz*/, 0xa0, }, | ||
434 | { 16 * 464 /*MHz*/, 0x90, }, | ||
435 | { 16 * 999.99 , 0x30, }, | ||
436 | }, | ||
437 | .config = 0x8e, | ||
438 | }, | ||
439 | [TUNER_MT2032] = { /* Microtune PAL|NTSC */ | ||
440 | .name = "MT20xx universal", | ||
178 | /* see mt20xx.c for details */ }, | 441 | /* see mt20xx.c for details */ }, |
179 | { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, | 442 | [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */ |
180 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | 443 | .name = "Temic PAL_BG (4106 FH5)", |
181 | { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, | 444 | .count = 3, |
182 | 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, | 445 | .ranges = { |
183 | { "Temic NTSC (4136 FY5)", TEMIC, NTSC, | 446 | { 16 * 141.00 /*MHz*/, 0xa0, }, |
184 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | 447 | { 16 * 464.00 /*MHz*/, 0x90, }, |
185 | { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, | 448 | { 16 * 999.99 , 0x30, }, |
186 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, | 449 | }, |
187 | { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, | 450 | .config = 0x8e, |
188 | 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | 451 | }, |
189 | { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, | 452 | [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */ |
190 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, | 453 | .name = "Temic PAL_DK/SECAM_L (4012 FY5)", |
454 | .count = 3, | ||
455 | .ranges = { | ||
456 | { 16 * 140.25 /*MHz*/, 0x02, }, | ||
457 | { 16 * 463.25 /*MHz*/, 0x04, }, | ||
458 | { 16 * 999.99 , 0x01, }, | ||
459 | }, | ||
460 | .config = 0x8e, | ||
461 | }, | ||
462 | [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */ | ||
463 | .name = "Temic NTSC (4136 FY5)", | ||
464 | .count = 3, | ||
465 | .ranges = { | ||
466 | { 16 * 158.00 /*MHz*/, 0xa0, }, | ||
467 | { 16 * 453.00 /*MHz*/, 0x90, }, | ||
468 | { 16 * 999.99 , 0x30, }, | ||
469 | }, | ||
470 | .config = 0x8e, | ||
471 | }, | ||
472 | [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */ | ||
473 | .name = "LG PAL (newer TAPC series)", | ||
474 | .count = 3, | ||
475 | .ranges = { | ||
476 | { 16 * 170.00 /*MHz*/, 0x01, }, | ||
477 | { 16 * 450.00 /*MHz*/, 0x02, }, | ||
478 | { 16 * 999.99 , 0x08, }, | ||
479 | }, | ||
480 | .config = 0x8e, | ||
481 | }, | ||
482 | [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */ | ||
483 | .name = "Philips PAL/SECAM multi (FM1216ME MK3)", | ||
484 | .count = 3, | ||
485 | .ranges = { | ||
486 | { 16 * 158.00 /*MHz*/, 0x01, }, | ||
487 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
488 | { 16 * 999.99 , 0x04, }, | ||
489 | }, | ||
490 | .config = 0x8e, | ||
491 | }, | ||
492 | [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */ | ||
493 | .name = "LG NTSC (newer TAPC series)", | ||
494 | .count = 3, | ||
495 | .ranges = { | ||
496 | { 16 * 170.00 /*MHz*/, 0x01, }, | ||
497 | { 16 * 450.00 /*MHz*/, 0x02, }, | ||
498 | { 16 * 999.99 , 0x08, }, | ||
499 | }, | ||
500 | .config = 0x8e, | ||
501 | }, | ||
191 | 502 | ||
192 | /* 40-49 */ | 503 | /* 40-49 */ |
193 | { "HITACHI V7-J180AT", HITACHI, NTSC, | 504 | [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */ |
194 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 }, | 505 | .name = "HITACHI V7-J180AT", |
195 | { "Philips PAL_MK (FI1216 MK)", Philips, PAL, | 506 | .count = 3, |
196 | 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, | 507 | .ranges = { |
197 | { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, | 508 | { 16 * 170.00 /*MHz*/, 0x01, }, |
198 | 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, | 509 | { 16 * 450.00 /*MHz*/, 0x02, }, |
199 | { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, | 510 | { 16 * 999.99 , 0x08, }, |
200 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | 511 | }, |
201 | { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, | 512 | .config = 0x8e, |
202 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | 513 | }, |
203 | { "Microtune 4049 FM5", Microtune, PAL, | 514 | [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */ |
204 | 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, | 515 | .name = "Philips PAL_MK (FI1216 MK)", |
205 | { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, | 516 | .count = 3, |
206 | 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, | 517 | .ranges = { |
207 | { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, | 518 | { 16 * 140.25 /*MHz*/, 0x01, }, |
208 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | 519 | { 16 * 463.25 /*MHz*/, 0xc2, }, |
209 | { "Tenna TNF 8831 BGFF)", Philips, PAL, | 520 | { 16 * 999.99 , 0xcf, }, |
210 | 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | 521 | }, |
211 | { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, | 522 | .config = 0x8e, |
212 | 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, | 523 | }, |
524 | [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ | ||
525 | .name = "Philips 1236D ATSC/NTSC dual in", | ||
526 | .count = 3, | ||
527 | .ranges = { | ||
528 | { 16 * 157.25 /*MHz*/, 0xa0, }, | ||
529 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
530 | { 16 * 999.99 , 0x30, }, | ||
531 | }, | ||
532 | .config = 0x8e, | ||
533 | }, | ||
534 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ | ||
535 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", | ||
536 | .count = 3, | ||
537 | .ranges = { | ||
538 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
539 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
540 | { 16 * 999.99 , 0x04, }, | ||
541 | }, | ||
542 | .config = 0x8e, | ||
543 | }, | ||
544 | [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */ | ||
545 | .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", | ||
546 | .count = 3, | ||
547 | .ranges = { | ||
548 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
549 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
550 | { 16 * 999.99 , 0x04, }, | ||
551 | }, | ||
552 | .config = 0x8e, | ||
553 | }, | ||
554 | [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */ | ||
555 | .name = "Microtune 4049 FM5", | ||
556 | .count = 3, | ||
557 | .ranges = { | ||
558 | { 16 * 141.00 /*MHz*/, 0xa0, }, | ||
559 | { 16 * 464.00 /*MHz*/, 0x90, }, | ||
560 | { 16 * 999.99 , 0x30, }, | ||
561 | }, | ||
562 | .config = 0x8e, | ||
563 | }, | ||
564 | [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */ | ||
565 | .name = "Panasonic VP27s/ENGE4324D", | ||
566 | .count = 3, | ||
567 | .ranges = { | ||
568 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
569 | { 16 * 454.00 /*MHz*/, 0x02, }, | ||
570 | { 16 * 999.99 , 0x08, }, | ||
571 | }, | ||
572 | .config = 0xce, | ||
573 | }, | ||
574 | [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ | ||
575 | .name = "LG NTSC (TAPE series)", | ||
576 | .count = 3, | ||
577 | .ranges = { | ||
578 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
579 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
580 | { 16 * 999.99 , 0x04, }, | ||
581 | }, | ||
582 | .config = 0x8e, | ||
583 | }, | ||
584 | [TUNER_TNF_8831BGFF] = { /* Philips PAL */ | ||
585 | .name = "Tenna TNF 8831 BGFF)", | ||
586 | .count = 3, | ||
587 | .ranges = { | ||
588 | { 16 * 161.25 /*MHz*/, 0xa0, }, | ||
589 | { 16 * 463.25 /*MHz*/, 0x90, }, | ||
590 | { 16 * 999.99 , 0x30, }, | ||
591 | }, | ||
592 | .config = 0x8e, | ||
593 | }, | ||
594 | [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */ | ||
595 | .name = "Microtune 4042 FI5 ATSC/NTSC dual in", | ||
596 | .count = 3, | ||
597 | .ranges = { | ||
598 | { 16 * 162.00 /*MHz*/, 0xa2, }, | ||
599 | { 16 * 457.00 /*MHz*/, 0x94, }, | ||
600 | { 16 * 999.99 , 0x31, }, | ||
601 | }, | ||
602 | .config = 0x8e, | ||
603 | }, | ||
213 | 604 | ||
214 | /* 50-59 */ | 605 | /* 50-59 */ |
215 | { "TCL 2002N", TCL, NTSC, | 606 | [TUNER_TCL_2002N] = { /* TCL NTSC */ |
216 | 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, | 607 | .name = "TCL 2002N", |
217 | { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, | 608 | .count = 3, |
218 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | 609 | .ranges = { |
219 | { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, | 610 | { 16 * 172.00 /*MHz*/, 0x01, }, |
220 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | 611 | { 16 * 448.00 /*MHz*/, 0x02, }, |
221 | { "Philips FQ1286", Philips, NTSC, | 612 | { 16 * 999.99 , 0x08, }, |
222 | 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ | 613 | }, |
223 | { "tda8290+75", Philips, PAL|NTSC, | 614 | .config = 0x8e, |
615 | }, | ||
616 | [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */ | ||
617 | .name = "Philips PAL/SECAM_D (FM 1256 I-H3)", | ||
618 | .count = 3, | ||
619 | .ranges = { | ||
620 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
621 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
622 | { 16 * 999.99 , 0x04, }, | ||
623 | }, | ||
624 | .config = 0x8e, | ||
625 | }, | ||
626 | [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */ | ||
627 | .name = "Thomson DTT 7610 (ATSC/NTSC)", | ||
628 | .count = 3, | ||
629 | .ranges = { | ||
630 | { 16 * 157.25 /*MHz*/, 0x39, }, | ||
631 | { 16 * 454.00 /*MHz*/, 0x3a, }, | ||
632 | { 16 * 999.99 , 0x3c, }, | ||
633 | }, | ||
634 | .config = 0x8e, | ||
635 | }, | ||
636 | [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ | ||
637 | .name = "Philips FQ1286", | ||
638 | .count = 3, | ||
639 | .ranges = { | ||
640 | { 16 * 160.00 /*MHz*/, 0x41, }, | ||
641 | { 16 * 454.00 /*MHz*/, 0x42, }, | ||
642 | { 16 * 999.99 , 0x04, }, | ||
643 | }, | ||
644 | .config = 0x8e, | ||
645 | }, | ||
646 | [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ | ||
647 | .name = "tda8290+75", | ||
224 | /* see tda8290.c for details */ }, | 648 | /* see tda8290.c for details */ }, |
225 | { "TCL 2002MB", TCL, PAL, | 649 | [TUNER_TCL_2002MB] = { /* TCL PAL */ |
226 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, | 650 | .name = "TCL 2002MB", |
227 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, | 651 | .count = 3, |
228 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, | 652 | .ranges = { |
229 | { "Philips FQ1236A MK4", Philips, NTSC, | 653 | { 16 * 170.00 /*MHz*/, 0x01, }, |
230 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | 654 | { 16 * 450.00 /*MHz*/, 0x02, }, |
231 | { "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC, | 655 | { 16 * 999.99 , 0x08, }, |
232 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, | 656 | }, |
233 | { "Ymec TVision TVF-5533MF", Philips, NTSC, | 657 | .config = 0xce, |
234 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, | 658 | }, |
659 | [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */ | ||
660 | .name = "Philips PAL/SECAM multi (FQ1216AME MK4)", | ||
661 | .count = 3, | ||
662 | .ranges = { | ||
663 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
664 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
665 | { 16 * 999.99 , 0x04, }, | ||
666 | }, | ||
667 | .config = 0xce, | ||
668 | }, | ||
669 | [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */ | ||
670 | .name = "Philips FQ1236A MK4", | ||
671 | .count = 3, | ||
672 | .ranges = { | ||
673 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
674 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
675 | { 16 * 999.99 , 0x04, }, | ||
676 | }, | ||
677 | .config = 0x8e, | ||
678 | }, | ||
679 | [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */ | ||
680 | .name = "Ymec TVision TVF-8531MF/8831MF/8731MF", | ||
681 | .count = 3, | ||
682 | .ranges = { | ||
683 | { 16 * 160.00 /*MHz*/, 0xa0, }, | ||
684 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
685 | { 16 * 999.99 , 0x30, }, | ||
686 | }, | ||
687 | .config = 0x8e, | ||
688 | }, | ||
689 | [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */ | ||
690 | .name = "Ymec TVision TVF-5533MF", | ||
691 | .count = 3, | ||
692 | .ranges = { | ||
693 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
694 | { 16 * 454.00 /*MHz*/, 0x02, }, | ||
695 | { 16 * 999.99 , 0x04, }, | ||
696 | }, | ||
697 | .config = 0x8e, | ||
698 | }, | ||
235 | 699 | ||
236 | /* 60-69 */ | 700 | /* 60-69 */ |
237 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, | 701 | [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */ |
238 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | 702 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
239 | { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, | 703 | .name = "Thomson DTT 761X (ATSC/NTSC)", |
240 | 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, | 704 | .count = 3, |
241 | { "Philips TEA5767HN FM Radio", Philips, RADIO, | 705 | .ranges = { |
706 | { 16 * 145.25 /*MHz*/, 0x39, }, | ||
707 | { 16 * 415.25 /*MHz*/, 0x3a, }, | ||
708 | { 16 * 999.99 , 0x3c, }, | ||
709 | }, | ||
710 | .config = 0x8e, | ||
711 | }, | ||
712 | [TUNER_TENA_9533_DI] = { /* Philips PAL */ | ||
713 | .name = "Tena TNF9533-D/IF/TNF9533-B/DF", | ||
714 | .count = 3, | ||
715 | .ranges = { | ||
716 | { 16 * 160.25 /*MHz*/, 0x01, }, | ||
717 | { 16 * 464.25 /*MHz*/, 0x02, }, | ||
718 | { 16 * 999.99 , 0x04, }, | ||
719 | }, | ||
720 | .config = 0x8e, | ||
721 | }, | ||
722 | [TUNER_TEA5767] = { /* Philips RADIO */ | ||
723 | .name = "Philips TEA5767HN FM Radio", | ||
242 | /* see tea5767.c for details */}, | 724 | /* see tea5767.c for details */}, |
243 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, | 725 | [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */ |
244 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, | 726 | .name = "Philips FMD1216ME MK3 Hybrid Tuner", |
245 | { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, | 727 | .count = 3, |
246 | 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, | 728 | .ranges = { |
247 | { "Ymec TVF66T5-B/DFF", Philips, PAL, | 729 | { 16 * 160.00 /*MHz*/, 0x51, }, |
248 | 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, | 730 | { 16 * 442.00 /*MHz*/, 0x52, }, |
249 | { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, | 731 | { 16 * 999.99 , 0x54, }, |
250 | 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, | 732 | }, |
251 | { "Philips TD1316 Hybrid Tuner", Philips, PAL, | 733 | .config = 0x86, |
252 | 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 }, | 734 | }, |
253 | { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC, | 735 | [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ |
254 | 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 }, | 736 | .name = "LG TDVS-H062F/TUA6034", |
255 | { "Tena TNF 5335 MF", Philips, NTSC, | 737 | .count = 3, |
256 | 16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 }, | 738 | .ranges = { |
739 | { 16 * 160.00 /*MHz*/, 0x01 }, | ||
740 | { 16 * 455.00 /*MHz*/, 0x02 }, | ||
741 | { 16 * 999.99 , 0x04 }, | ||
742 | }, | ||
743 | .config = 0x8e, | ||
744 | }, | ||
745 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ | ||
746 | .name = "Ymec TVF66T5-B/DFF", | ||
747 | .count = 3, | ||
748 | .ranges = { | ||
749 | { 16 * 160.25 /*MHz*/, 0x01, }, | ||
750 | { 16 * 464.25 /*MHz*/, 0x02, }, | ||
751 | { 16 * 999.99 , 0x08, }, | ||
752 | }, | ||
753 | .config = 0x8e, | ||
754 | }, | ||
755 | [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */ | ||
756 | .name = "LG NTSC (TALN mini series)", | ||
757 | .count = 3, | ||
758 | .ranges = { | ||
759 | { 16 * 137.25 /*MHz*/, 0x01, }, | ||
760 | { 16 * 373.25 /*MHz*/, 0x02, }, | ||
761 | { 16 * 999.99 , 0x08, }, | ||
762 | }, | ||
763 | .config = 0x8e, | ||
764 | }, | ||
765 | [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ | ||
766 | .name = "Philips TD1316 Hybrid Tuner", | ||
767 | .count = 3, | ||
768 | .ranges = { | ||
769 | { 16 * 160.00 /*MHz*/, 0xa1, }, | ||
770 | { 16 * 442.00 /*MHz*/, 0xa2, }, | ||
771 | { 16 * 999.99 , 0xa4, }, | ||
772 | }, | ||
773 | .config = 0xc8, | ||
774 | }, | ||
775 | [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ | ||
776 | .name = "Philips TUV1236D ATSC/NTSC dual in", | ||
777 | .count = 3, | ||
778 | .ranges = { | ||
779 | { 16 * 157.25 /*MHz*/, 0x01, }, | ||
780 | { 16 * 454.00 /*MHz*/, 0x02, }, | ||
781 | { 16 * 999.99 , 0x04, }, | ||
782 | }, | ||
783 | .config = 0xce, | ||
784 | }, | ||
785 | [TUNER_TNF_5335MF] = { /* Philips NTSC */ | ||
786 | .name = "Tena TNF 5335 MF", | ||
787 | .count = 3, | ||
788 | .ranges = { | ||
789 | { 16 * 157.25 /*MHz*/, 0x01, }, | ||
790 | { 16 * 454.00 /*MHz*/, 0x02, }, | ||
791 | { 16 * 999.99 , 0x04, }, | ||
792 | }, | ||
793 | .config = 0x8e, | ||
794 | }, | ||
257 | }; | 795 | }; |
258 | 796 | ||
259 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 797 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
@@ -305,20 +843,19 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
305 | u16 div; | 843 | u16 div; |
306 | struct tunertype *tun; | 844 | struct tunertype *tun; |
307 | unsigned char buffer[4]; | 845 | unsigned char buffer[4]; |
308 | int rc; | 846 | int rc, IFPCoff, i; |
309 | 847 | ||
310 | tun = &tuners[t->type]; | 848 | tun = &tuners[t->type]; |
311 | if (freq < tun->thresh1) { | 849 | for (i = 0; i < tun->count; i++) { |
312 | config = tun->VHF_L; | 850 | if (freq > tun->ranges[i].thresh) |
313 | tuner_dbg("tv: VHF lowrange\n"); | 851 | continue; |
314 | } else if (freq < tun->thresh2) { | 852 | break; |
315 | config = tun->VHF_H; | ||
316 | tuner_dbg("tv: VHF high range\n"); | ||
317 | } else { | ||
318 | config = tun->UHF; | ||
319 | tuner_dbg("tv: UHF range\n"); | ||
320 | } | 853 | } |
321 | 854 | config = tun->ranges[i].cb; | |
855 | /* i == 0 -> VHF_LO */ | ||
856 | /* i == 1 -> VHF_HI */ | ||
857 | /* i == 2 -> UHF */ | ||
858 | tuner_dbg("tv: range %d\n",i); | ||
322 | 859 | ||
323 | /* tv norm specific stuff for multi-norm tuners */ | 860 | /* tv norm specific stuff for multi-norm tuners */ |
324 | switch (t->type) { | 861 | switch (t->type) { |
@@ -420,7 +957,37 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
420 | * frequency in case (wanted frequency < current frequency). | 957 | * frequency in case (wanted frequency < current frequency). |
421 | */ | 958 | */ |
422 | 959 | ||
423 | div=freq + tun->IFPCoff; | 960 | /* IFPCoff = Video Intermediate Frequency - Vif: |
961 | 940 =16*58.75 NTSC/J (Japan) | ||
962 | 732 =16*45.75 M/N STD | ||
963 | 704 =16*44 ATSC (at DVB code) | ||
964 | 632 =16*39.50 I U.K. | ||
965 | 622.4=16*38.90 B/G D/K I, L STD | ||
966 | 592 =16*37.00 D China | ||
967 | 590 =16.36.875 B Australia | ||
968 | 543.2=16*33.95 L' STD | ||
969 | 171.2=16*10.70 FM Radio (at set_radio_freq) | ||
970 | */ | ||
971 | |||
972 | if (t->std == V4L2_STD_NTSC_M_JP) { | ||
973 | IFPCoff = 940; | ||
974 | } else if ((t->std & V4L2_STD_MN) && | ||
975 | !(t->std & ~V4L2_STD_MN)) { | ||
976 | IFPCoff = 732; | ||
977 | } else if (t->std == V4L2_STD_SECAM_LC) { | ||
978 | IFPCoff = 543; | ||
979 | } else { | ||
980 | IFPCoff = 623; | ||
981 | } | ||
982 | |||
983 | div=freq + IFPCoff + offset; | ||
984 | |||
985 | tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", | ||
986 | freq / 16, freq % 16 * 100 / 16, | ||
987 | IFPCoff / 16, IFPCoff % 16 * 100 / 16, | ||
988 | offset / 16, offset % 16 * 100 / 16, | ||
989 | div); | ||
990 | |||
424 | if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { | 991 | if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { |
425 | buffer[0] = tun->config; | 992 | buffer[0] = tun->config; |
426 | buffer[1] = config; | 993 | buffer[1] = config; |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 0292c5abf14a..b582943a0d3e 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | 32 | ||
33 | #include <media/audiochip.h> | 33 | #include <media/audiochip.h> |
34 | #include <media/v4l2-common.h> | ||
34 | 35 | ||
35 | #include "tvaudio.h" | 36 | #include "tvaudio.h" |
36 | 37 | ||
@@ -46,17 +47,6 @@ MODULE_LICENSE("GPL"); | |||
46 | 47 | ||
47 | #define UNSET (-1U) | 48 | #define UNSET (-1U) |
48 | 49 | ||
49 | #define tvaudio_info(fmt, arg...) do {\ | ||
50 | printk(KERN_INFO "tvaudio %d-%04x: " fmt, \ | ||
51 | chip->c.adapter->nr, chip->c.addr , ##arg); } while (0) | ||
52 | #define tvaudio_warn(fmt, arg...) do {\ | ||
53 | printk(KERN_WARNING "tvaudio %d-%04x: " fmt, \ | ||
54 | chip->c.adapter->nr, chip->c.addr , ##arg); } while (0) | ||
55 | #define tvaudio_dbg(fmt, arg...) do {\ | ||
56 | if (debug) \ | ||
57 | printk(KERN_INFO "tvaudio %d-%04x: " fmt, \ | ||
58 | chip->c.adapter->nr, chip->c.addr , ##arg); } while (0) | ||
59 | |||
60 | /* ---------------------------------------------------------------------- */ | 50 | /* ---------------------------------------------------------------------- */ |
61 | /* our structs */ | 51 | /* our structs */ |
62 | 52 | ||
@@ -131,7 +121,7 @@ struct CHIPSTATE { | |||
131 | /* current settings */ | 121 | /* current settings */ |
132 | __u16 left,right,treble,bass,mode; | 122 | __u16 left,right,treble,bass,mode; |
133 | int prevmode; | 123 | int prevmode; |
134 | int norm; | 124 | int radio; |
135 | 125 | ||
136 | /* thread */ | 126 | /* thread */ |
137 | pid_t tpid; | 127 | pid_t tpid; |
@@ -142,8 +132,6 @@ struct CHIPSTATE { | |||
142 | int watch_stereo; | 132 | int watch_stereo; |
143 | }; | 133 | }; |
144 | 134 | ||
145 | #define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */ | ||
146 | |||
147 | /* ---------------------------------------------------------------------- */ | 135 | /* ---------------------------------------------------------------------- */ |
148 | /* i2c addresses */ | 136 | /* i2c addresses */ |
149 | 137 | ||
@@ -171,23 +159,23 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
171 | unsigned char buffer[2]; | 159 | unsigned char buffer[2]; |
172 | 160 | ||
173 | if (-1 == subaddr) { | 161 | if (-1 == subaddr) { |
174 | tvaudio_dbg("%s: chip_write: 0x%x\n", | 162 | v4l_dbg(1, &chip->c, "%s: chip_write: 0x%x\n", |
175 | chip->c.name, val); | 163 | chip->c.name, val); |
176 | chip->shadow.bytes[1] = val; | 164 | chip->shadow.bytes[1] = val; |
177 | buffer[0] = val; | 165 | buffer[0] = val; |
178 | if (1 != i2c_master_send(&chip->c,buffer,1)) { | 166 | if (1 != i2c_master_send(&chip->c,buffer,1)) { |
179 | tvaudio_warn("%s: I/O error (write 0x%x)\n", | 167 | v4l_warn(&chip->c, "%s: I/O error (write 0x%x)\n", |
180 | chip->c.name, val); | 168 | chip->c.name, val); |
181 | return -1; | 169 | return -1; |
182 | } | 170 | } |
183 | } else { | 171 | } else { |
184 | tvaudio_dbg("%s: chip_write: reg%d=0x%x\n", | 172 | v4l_dbg(1, &chip->c, "%s: chip_write: reg%d=0x%x\n", |
185 | chip->c.name, subaddr, val); | 173 | chip->c.name, subaddr, val); |
186 | chip->shadow.bytes[subaddr+1] = val; | 174 | chip->shadow.bytes[subaddr+1] = val; |
187 | buffer[0] = subaddr; | 175 | buffer[0] = subaddr; |
188 | buffer[1] = val; | 176 | buffer[1] = val; |
189 | if (2 != i2c_master_send(&chip->c,buffer,2)) { | 177 | if (2 != i2c_master_send(&chip->c,buffer,2)) { |
190 | tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n", | 178 | v4l_warn(&chip->c, "%s: I/O error (write reg%d=0x%x)\n", |
191 | chip->c.name, subaddr, val); | 179 | chip->c.name, subaddr, val); |
192 | return -1; | 180 | return -1; |
193 | } | 181 | } |
@@ -212,11 +200,11 @@ static int chip_read(struct CHIPSTATE *chip) | |||
212 | unsigned char buffer; | 200 | unsigned char buffer; |
213 | 201 | ||
214 | if (1 != i2c_master_recv(&chip->c,&buffer,1)) { | 202 | if (1 != i2c_master_recv(&chip->c,&buffer,1)) { |
215 | tvaudio_warn("%s: I/O error (read)\n", | 203 | v4l_warn(&chip->c, "%s: I/O error (read)\n", |
216 | chip->c.name); | 204 | chip->c.name); |
217 | return -1; | 205 | return -1; |
218 | } | 206 | } |
219 | tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name, buffer); | 207 | v4l_dbg(1, &chip->c, "%s: chip_read: 0x%x\n",chip->c.name, buffer); |
220 | return buffer; | 208 | return buffer; |
221 | } | 209 | } |
222 | 210 | ||
@@ -231,10 +219,10 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) | |||
231 | write[0] = subaddr; | 219 | write[0] = subaddr; |
232 | 220 | ||
233 | if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { | 221 | if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { |
234 | tvaudio_warn("%s: I/O error (read2)\n", chip->c.name); | 222 | v4l_warn(&chip->c, "%s: I/O error (read2)\n", chip->c.name); |
235 | return -1; | 223 | return -1; |
236 | } | 224 | } |
237 | tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n", | 225 | v4l_dbg(1, &chip->c, "%s: chip_read2: reg%d=0x%x\n", |
238 | chip->c.name, subaddr,read[0]); | 226 | chip->c.name, subaddr,read[0]); |
239 | return read[0]; | 227 | return read[0]; |
240 | } | 228 | } |
@@ -247,7 +235,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) | |||
247 | return 0; | 235 | return 0; |
248 | 236 | ||
249 | /* update our shadow register set; print bytes if (debug > 0) */ | 237 | /* update our shadow register set; print bytes if (debug > 0) */ |
250 | tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:", | 238 | v4l_dbg(1, &chip->c, "%s: chip_cmd(%s): reg=%d, data:", |
251 | chip->c.name, name,cmd->bytes[0]); | 239 | chip->c.name, name,cmd->bytes[0]); |
252 | for (i = 1; i < cmd->count; i++) { | 240 | for (i = 1; i < cmd->count; i++) { |
253 | if (debug) | 241 | if (debug) |
@@ -259,7 +247,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) | |||
259 | 247 | ||
260 | /* send data to the chip */ | 248 | /* send data to the chip */ |
261 | if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { | 249 | if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { |
262 | tvaudio_warn("%s: I/O error (%s)\n", chip->c.name, name); | 250 | v4l_warn(&chip->c, "%s: I/O error (%s)\n", chip->c.name, name); |
263 | return -1; | 251 | return -1; |
264 | } | 252 | } |
265 | return 0; | 253 | return 0; |
@@ -286,7 +274,7 @@ static int chip_thread(void *data) | |||
286 | 274 | ||
287 | daemonize("%s", chip->c.name); | 275 | daemonize("%s", chip->c.name); |
288 | allow_signal(SIGTERM); | 276 | allow_signal(SIGTERM); |
289 | tvaudio_dbg("%s: thread started\n", chip->c.name); | 277 | v4l_dbg(1, &chip->c, "%s: thread started\n", chip->c.name); |
290 | 278 | ||
291 | for (;;) { | 279 | for (;;) { |
292 | add_wait_queue(&chip->wq, &wait); | 280 | add_wait_queue(&chip->wq, &wait); |
@@ -298,10 +286,10 @@ static int chip_thread(void *data) | |||
298 | try_to_freeze(); | 286 | try_to_freeze(); |
299 | if (chip->done || signal_pending(current)) | 287 | if (chip->done || signal_pending(current)) |
300 | break; | 288 | break; |
301 | tvaudio_dbg("%s: thread wakeup\n", chip->c.name); | 289 | v4l_dbg(1, &chip->c, "%s: thread wakeup\n", chip->c.name); |
302 | 290 | ||
303 | /* don't do anything for radio or if mode != auto */ | 291 | /* don't do anything for radio or if mode != auto */ |
304 | if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0) | 292 | if (chip->radio || chip->mode != 0) |
305 | continue; | 293 | continue; |
306 | 294 | ||
307 | /* have a look what's going on */ | 295 | /* have a look what's going on */ |
@@ -311,7 +299,7 @@ static int chip_thread(void *data) | |||
311 | mod_timer(&chip->wt, jiffies+2*HZ); | 299 | mod_timer(&chip->wt, jiffies+2*HZ); |
312 | } | 300 | } |
313 | 301 | ||
314 | tvaudio_dbg("%s: thread exiting\n", chip->c.name); | 302 | v4l_dbg(1, &chip->c, "%s: thread exiting\n", chip->c.name); |
315 | complete_and_exit(&chip->texit, 0); | 303 | complete_and_exit(&chip->texit, 0); |
316 | return 0; | 304 | return 0; |
317 | } | 305 | } |
@@ -324,7 +312,7 @@ static void generic_checkmode(struct CHIPSTATE *chip) | |||
324 | if (mode == chip->prevmode) | 312 | if (mode == chip->prevmode) |
325 | return; | 313 | return; |
326 | 314 | ||
327 | tvaudio_dbg("%s: thread checkmode\n", chip->c.name); | 315 | v4l_dbg(1, &chip->c, "%s: thread checkmode\n", chip->c.name); |
328 | chip->prevmode = mode; | 316 | chip->prevmode = mode; |
329 | 317 | ||
330 | if (mode & VIDEO_SOUND_STEREO) | 318 | if (mode & VIDEO_SOUND_STEREO) |
@@ -371,7 +359,7 @@ static int tda9840_getmode(struct CHIPSTATE *chip) | |||
371 | if (val & TDA9840_ST_STEREO) | 359 | if (val & TDA9840_ST_STEREO) |
372 | mode |= VIDEO_SOUND_STEREO; | 360 | mode |= VIDEO_SOUND_STEREO; |
373 | 361 | ||
374 | tvaudio_dbg ("tda9840_getmode(): raw chip read: %d, return: %d\n", | 362 | v4l_dbg(1, &chip->c, "tda9840_getmode(): raw chip read: %d, return: %d\n", |
375 | val, mode); | 363 | val, mode); |
376 | return mode; | 364 | return mode; |
377 | } | 365 | } |
@@ -667,7 +655,7 @@ static int tda9873_getmode(struct CHIPSTATE *chip) | |||
667 | mode |= VIDEO_SOUND_STEREO; | 655 | mode |= VIDEO_SOUND_STEREO; |
668 | if (val & TDA9873_DUAL) | 656 | if (val & TDA9873_DUAL) |
669 | mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; | 657 | mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; |
670 | tvaudio_dbg ("tda9873_getmode(): raw chip read: %d, return: %d\n", | 658 | v4l_dbg(1, &chip->c, "tda9873_getmode(): raw chip read: %d, return: %d\n", |
671 | val, mode); | 659 | val, mode); |
672 | return mode; | 660 | return mode; |
673 | } | 661 | } |
@@ -678,12 +666,12 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode) | |||
678 | /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ | 666 | /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ |
679 | 667 | ||
680 | if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { | 668 | if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { |
681 | tvaudio_dbg("tda9873_setmode(): external input\n"); | 669 | v4l_dbg(1, &chip->c, "tda9873_setmode(): external input\n"); |
682 | return; | 670 | return; |
683 | } | 671 | } |
684 | 672 | ||
685 | tvaudio_dbg("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); | 673 | v4l_dbg(1, &chip->c, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); |
686 | tvaudio_dbg("tda9873_setmode(): sw_data = %d\n", sw_data); | 674 | v4l_dbg(1, &chip->c, "tda9873_setmode(): sw_data = %d\n", sw_data); |
687 | 675 | ||
688 | switch (mode) { | 676 | switch (mode) { |
689 | case VIDEO_SOUND_MONO: | 677 | case VIDEO_SOUND_MONO: |
@@ -704,7 +692,7 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode) | |||
704 | } | 692 | } |
705 | 693 | ||
706 | chip_write(chip, TDA9873_SW, sw_data); | 694 | chip_write(chip, TDA9873_SW, sw_data); |
707 | tvaudio_dbg("tda9873_setmode(): req. mode %d; chip_write: %d\n", | 695 | v4l_dbg(1, &chip->c, "tda9873_setmode(): req. mode %d; chip_write: %d\n", |
708 | mode, sw_data); | 696 | mode, sw_data); |
709 | } | 697 | } |
710 | 698 | ||
@@ -843,7 +831,7 @@ static int tda9874a_setup(struct CHIPSTATE *chip) | |||
843 | chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); | 831 | chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); |
844 | chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */ | 832 | chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */ |
845 | } | 833 | } |
846 | tvaudio_dbg("tda9874a_setup(): %s [0x%02X].\n", | 834 | v4l_dbg(1, &chip->c, "tda9874a_setup(): %s [0x%02X].\n", |
847 | tda9874a_modelist[tda9874a_STD].name,tda9874a_STD); | 835 | tda9874a_modelist[tda9874a_STD].name,tda9874a_STD); |
848 | return 1; | 836 | return 1; |
849 | } | 837 | } |
@@ -886,7 +874,7 @@ static int tda9874a_getmode(struct CHIPSTATE *chip) | |||
886 | mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; | 874 | mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; |
887 | } | 875 | } |
888 | 876 | ||
889 | tvaudio_dbg("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", | 877 | v4l_dbg(1, &chip->c, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", |
890 | dsr, nsr, necr, mode); | 878 | dsr, nsr, necr, mode); |
891 | return mode; | 879 | return mode; |
892 | } | 880 | } |
@@ -932,7 +920,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode) | |||
932 | chip_write(chip, TDA9874A_AOSR, aosr); | 920 | chip_write(chip, TDA9874A_AOSR, aosr); |
933 | chip_write(chip, TDA9874A_MDACOSR, mdacosr); | 921 | chip_write(chip, TDA9874A_MDACOSR, mdacosr); |
934 | 922 | ||
935 | tvaudio_dbg("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", | 923 | v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", |
936 | mode, aosr, mdacosr); | 924 | mode, aosr, mdacosr); |
937 | 925 | ||
938 | } else { /* dic == 0x07 */ | 926 | } else { /* dic == 0x07 */ |
@@ -967,7 +955,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode) | |||
967 | chip_write(chip, TDA9874A_FMMR, fmmr); | 955 | chip_write(chip, TDA9874A_FMMR, fmmr); |
968 | chip_write(chip, TDA9874A_AOSR, aosr); | 956 | chip_write(chip, TDA9874A_AOSR, aosr); |
969 | 957 | ||
970 | tvaudio_dbg("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", | 958 | v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", |
971 | mode, fmmr, aosr); | 959 | mode, fmmr, aosr); |
972 | } | 960 | } |
973 | } | 961 | } |
@@ -981,10 +969,10 @@ static int tda9874a_checkit(struct CHIPSTATE *chip) | |||
981 | if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) | 969 | if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) |
982 | return 0; | 970 | return 0; |
983 | 971 | ||
984 | tvaudio_dbg("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); | 972 | v4l_dbg(1, &chip->c, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); |
985 | 973 | ||
986 | if((dic == 0x11)||(dic == 0x07)) { | 974 | if((dic == 0x11)||(dic == 0x07)) { |
987 | tvaudio_info("found tda9874%s.\n", (dic == 0x11) ? "a":"h"); | 975 | v4l_info(&chip->c, "found tda9874%s.\n", (dic == 0x11) ? "a":"h"); |
988 | tda9874a_dic = dic; /* remember device id. */ | 976 | tda9874a_dic = dic; /* remember device id. */ |
989 | return 1; | 977 | return 1; |
990 | } | 978 | } |
@@ -1196,7 +1184,7 @@ static int ta8874z_getmode(struct CHIPSTATE *chip) | |||
1196 | }else if (!(val & TA8874Z_B0)){ | 1184 | }else if (!(val & TA8874Z_B0)){ |
1197 | mode |= VIDEO_SOUND_STEREO; | 1185 | mode |= VIDEO_SOUND_STEREO; |
1198 | } | 1186 | } |
1199 | /* tvaudio_dbg ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */ | 1187 | /* v4l_dbg(1, &chip->c, "ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */ |
1200 | return mode; | 1188 | return mode; |
1201 | } | 1189 | } |
1202 | 1190 | ||
@@ -1209,7 +1197,7 @@ static void ta8874z_setmode(struct CHIPSTATE *chip, int mode) | |||
1209 | { | 1197 | { |
1210 | int update = 1; | 1198 | int update = 1; |
1211 | audiocmd *t = NULL; | 1199 | audiocmd *t = NULL; |
1212 | tvaudio_dbg("ta8874z_setmode(): mode: 0x%02x\n", mode); | 1200 | v4l_dbg(1, &chip->c, "ta8874z_setmode(): mode: 0x%02x\n", mode); |
1213 | 1201 | ||
1214 | switch(mode){ | 1202 | switch(mode){ |
1215 | case VIDEO_SOUND_MONO: | 1203 | case VIDEO_SOUND_MONO: |
@@ -1490,7 +1478,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1490 | i2c_set_clientdata(&chip->c, chip); | 1478 | i2c_set_clientdata(&chip->c, chip); |
1491 | 1479 | ||
1492 | /* find description for the chip */ | 1480 | /* find description for the chip */ |
1493 | tvaudio_dbg("chip found @ 0x%x\n", addr<<1); | 1481 | v4l_dbg(1, &chip->c, "chip found @ 0x%x\n", addr<<1); |
1494 | for (desc = chiplist; desc->name != NULL; desc++) { | 1482 | for (desc = chiplist; desc->name != NULL; desc++) { |
1495 | if (0 == *(desc->insmodopt)) | 1483 | if (0 == *(desc->insmodopt)) |
1496 | continue; | 1484 | continue; |
@@ -1502,12 +1490,12 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1502 | break; | 1490 | break; |
1503 | } | 1491 | } |
1504 | if (desc->name == NULL) { | 1492 | if (desc->name == NULL) { |
1505 | tvaudio_dbg("no matching chip description found\n"); | 1493 | v4l_dbg(1, &chip->c, "no matching chip description found\n"); |
1506 | return -EIO; | 1494 | return -EIO; |
1507 | } | 1495 | } |
1508 | tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name); | 1496 | v4l_info(&chip->c, "%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name); |
1509 | if (desc->flags) { | 1497 | if (desc->flags) { |
1510 | tvaudio_dbg("matches:%s%s%s.\n", | 1498 | v4l_dbg(1, &chip->c, "matches:%s%s%s.\n", |
1511 | (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", | 1499 | (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", |
1512 | (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", | 1500 | (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", |
1513 | (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); | 1501 | (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); |
@@ -1550,7 +1538,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1550 | init_completion(&chip->texit); | 1538 | init_completion(&chip->texit); |
1551 | chip->tpid = kernel_thread(chip_thread,(void *)chip,0); | 1539 | chip->tpid = kernel_thread(chip_thread,(void *)chip,0); |
1552 | if (chip->tpid < 0) | 1540 | if (chip->tpid < 0) |
1553 | tvaudio_warn("%s: kernel_thread() failed\n", | 1541 | v4l_warn(&chip->c, "%s: kernel_thread() failed\n", |
1554 | chip->c.name); | 1542 | chip->c.name); |
1555 | wake_up_interruptible(&chip->wq); | 1543 | wake_up_interruptible(&chip->wq); |
1556 | } | 1544 | } |
@@ -1563,17 +1551,8 @@ static int chip_probe(struct i2c_adapter *adap) | |||
1563 | because dedicated drivers are used */ | 1551 | because dedicated drivers are used */ |
1564 | if ((adap->id == I2C_HW_SAA7146)) | 1552 | if ((adap->id == I2C_HW_SAA7146)) |
1565 | return 0; | 1553 | return 0; |
1566 | #ifdef I2C_CLASS_TV_ANALOG | ||
1567 | if (adap->class & I2C_CLASS_TV_ANALOG) | 1554 | if (adap->class & I2C_CLASS_TV_ANALOG) |
1568 | return i2c_probe(adap, &addr_data, chip_attach); | 1555 | return i2c_probe(adap, &addr_data, chip_attach); |
1569 | #else | ||
1570 | switch (adap->id) { | ||
1571 | case I2C_HW_B_BT848: | ||
1572 | case I2C_HW_B_RIVA: | ||
1573 | case I2C_HW_SAA7134: | ||
1574 | return i2c_probe(adap, &addr_data, chip_attach); | ||
1575 | } | ||
1576 | #endif | ||
1577 | return 0; | 1556 | return 0; |
1578 | } | 1557 | } |
1579 | 1558 | ||
@@ -1604,7 +1583,7 @@ static int chip_command(struct i2c_client *client, | |||
1604 | struct CHIPSTATE *chip = i2c_get_clientdata(client); | 1583 | struct CHIPSTATE *chip = i2c_get_clientdata(client); |
1605 | struct CHIPDESC *desc = chiplist + chip->type; | 1584 | struct CHIPDESC *desc = chiplist + chip->type; |
1606 | 1585 | ||
1607 | tvaudio_dbg("%s: chip_command 0x%x\n", chip->c.name, cmd); | 1586 | v4l_dbg(1, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd); |
1608 | 1587 | ||
1609 | switch (cmd) { | 1588 | switch (cmd) { |
1610 | case AUDC_SET_INPUT: | 1589 | case AUDC_SET_INPUT: |
@@ -1617,7 +1596,7 @@ static int chip_command(struct i2c_client *client, | |||
1617 | break; | 1596 | break; |
1618 | 1597 | ||
1619 | case AUDC_SET_RADIO: | 1598 | case AUDC_SET_RADIO: |
1620 | chip->norm = VIDEO_MODE_RADIO; | 1599 | chip->radio = 1; |
1621 | chip->watch_stereo = 0; | 1600 | chip->watch_stereo = 0; |
1622 | /* del_timer(&chip->wt); */ | 1601 | /* del_timer(&chip->wt); */ |
1623 | break; | 1602 | break; |
@@ -1643,7 +1622,7 @@ static int chip_command(struct i2c_client *client, | |||
1643 | va->bass = chip->bass; | 1622 | va->bass = chip->bass; |
1644 | va->treble = chip->treble; | 1623 | va->treble = chip->treble; |
1645 | } | 1624 | } |
1646 | if (chip->norm != VIDEO_MODE_RADIO) { | 1625 | if (!chip->radio) { |
1647 | if (desc->getmode) | 1626 | if (desc->getmode) |
1648 | va->mode = desc->getmode(chip); | 1627 | va->mode = desc->getmode(chip); |
1649 | else | 1628 | else |
@@ -1678,15 +1657,80 @@ static int chip_command(struct i2c_client *client, | |||
1678 | } | 1657 | } |
1679 | break; | 1658 | break; |
1680 | } | 1659 | } |
1681 | case VIDIOCSCHAN: | 1660 | |
1661 | case VIDIOC_S_TUNER: | ||
1682 | { | 1662 | { |
1683 | struct video_channel *vc = arg; | 1663 | struct v4l2_tuner *vt = arg; |
1664 | int mode = 0; | ||
1684 | 1665 | ||
1685 | chip->norm = vc->norm; | 1666 | switch (vt->audmode) { |
1667 | case V4L2_TUNER_MODE_MONO: | ||
1668 | mode = VIDEO_SOUND_MONO; | ||
1669 | break; | ||
1670 | case V4L2_TUNER_MODE_STEREO: | ||
1671 | mode = VIDEO_SOUND_STEREO; | ||
1672 | break; | ||
1673 | case V4L2_TUNER_MODE_LANG1: | ||
1674 | mode = VIDEO_SOUND_LANG1; | ||
1675 | break; | ||
1676 | case V4L2_TUNER_MODE_LANG2: | ||
1677 | mode = VIDEO_SOUND_LANG2; | ||
1678 | break; | ||
1679 | default: | ||
1680 | break; | ||
1681 | } | ||
1682 | |||
1683 | if (desc->setmode && mode) { | ||
1684 | chip->watch_stereo = 0; | ||
1685 | /* del_timer(&chip->wt); */ | ||
1686 | chip->mode = mode; | ||
1687 | desc->setmode(chip, mode); | ||
1688 | } | ||
1686 | break; | 1689 | break; |
1687 | } | 1690 | } |
1688 | case VIDIOCSFREQ: | 1691 | |
1692 | case VIDIOC_G_TUNER: | ||
1689 | { | 1693 | { |
1694 | struct v4l2_tuner *vt = arg; | ||
1695 | int mode = VIDEO_SOUND_MONO; | ||
1696 | |||
1697 | if (chip->radio) | ||
1698 | break; | ||
1699 | vt->audmode = 0; | ||
1700 | vt->rxsubchans = 0; | ||
1701 | vt->capability = V4L2_TUNER_CAP_STEREO | | ||
1702 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | ||
1703 | |||
1704 | if (desc->getmode) | ||
1705 | mode = desc->getmode(chip); | ||
1706 | |||
1707 | if (mode & VIDEO_SOUND_MONO) | ||
1708 | vt->rxsubchans |= V4L2_TUNER_SUB_MONO; | ||
1709 | if (mode & VIDEO_SOUND_STEREO) | ||
1710 | vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
1711 | if (mode & VIDEO_SOUND_LANG1) | ||
1712 | vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 | | ||
1713 | V4L2_TUNER_SUB_LANG2; | ||
1714 | |||
1715 | mode = chip->mode; | ||
1716 | if (mode & VIDEO_SOUND_MONO) | ||
1717 | vt->audmode = V4L2_TUNER_MODE_MONO; | ||
1718 | if (mode & VIDEO_SOUND_STEREO) | ||
1719 | vt->audmode = V4L2_TUNER_MODE_STEREO; | ||
1720 | if (mode & VIDEO_SOUND_LANG1) | ||
1721 | vt->audmode = V4L2_TUNER_MODE_LANG1; | ||
1722 | if (mode & VIDEO_SOUND_LANG2) | ||
1723 | vt->audmode = V4L2_TUNER_MODE_LANG2; | ||
1724 | break; | ||
1725 | } | ||
1726 | |||
1727 | case VIDIOCSCHAN: | ||
1728 | case VIDIOC_S_STD: | ||
1729 | chip->radio = 0; | ||
1730 | break; | ||
1731 | |||
1732 | case VIDIOCSFREQ: | ||
1733 | case VIDIOC_S_FREQUENCY: | ||
1690 | chip->mode = 0; /* automatic */ | 1734 | chip->mode = 0; /* automatic */ |
1691 | if (desc->checkmode) { | 1735 | if (desc->checkmode) { |
1692 | desc->setmode(chip,VIDEO_SOUND_MONO); | 1736 | desc->setmode(chip,VIDEO_SOUND_MONO); |
@@ -1695,15 +1739,14 @@ static int chip_command(struct i2c_client *client, | |||
1695 | mod_timer(&chip->wt, jiffies+2*HZ); | 1739 | mod_timer(&chip->wt, jiffies+2*HZ); |
1696 | /* the thread will call checkmode() later */ | 1740 | /* the thread will call checkmode() later */ |
1697 | } | 1741 | } |
1698 | } | 1742 | break; |
1699 | } | 1743 | } |
1700 | return 0; | 1744 | return 0; |
1701 | } | 1745 | } |
1702 | 1746 | ||
1703 | |||
1704 | static struct i2c_driver driver = { | 1747 | static struct i2c_driver driver = { |
1705 | .driver = { | 1748 | .driver = { |
1706 | .name = "generic i2c audio driver", | 1749 | .name = "tvaudio", |
1707 | }, | 1750 | }, |
1708 | .id = I2C_DRIVERID_TVAUDIO, | 1751 | .id = I2C_DRIVERID_TVAUDIO, |
1709 | .attach_adapter = chip_probe, | 1752 | .attach_adapter = chip_probe, |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 8ac4cb82a459..fd0acc5da667 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | #include <media/tuner.h> | 41 | #include <media/tuner.h> |
42 | #include <media/tveeprom.h> | 42 | #include <media/tveeprom.h> |
43 | #include <media/v4l2-common.h> | ||
43 | #include <media/audiochip.h> | 44 | #include <media/audiochip.h> |
44 | 45 | ||
45 | MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); | 46 | MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); |
@@ -52,21 +53,19 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
52 | 53 | ||
53 | #define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown") | 54 | #define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown") |
54 | 55 | ||
55 | #define tveeprom_info(fmt, arg...) do {\ | 56 | #define tveeprom_info(fmt, arg...) \ |
56 | printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ | 57 | v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg) |
57 | c->adapter->nr, c->addr , ##arg); } while (0) | 58 | #define tveeprom_warn(fmt, arg...) \ |
58 | #define tveeprom_warn(fmt, arg...) do {\ | 59 | v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg) |
59 | printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ | 60 | #define tveeprom_dbg(fmt, arg...) do { \ |
60 | c->adapter->nr, c->addr , ##arg); } while (0) | ||
61 | #define tveeprom_dbg(fmt, arg...) do {\ | ||
62 | if (debug) \ | 61 | if (debug) \ |
63 | printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ | 62 | v4l_printk(KERN_DEBUG, "tveeprom", c->adapter, c->addr, fmt , ## arg); \ |
64 | c->adapter->nr, c->addr , ##arg); } while (0) | 63 | } while (0) |
65 | |||
66 | |||
67 | /* ----------------------------------------------------------------------- */ | ||
68 | /* some hauppauge specific stuff */ | ||
69 | 64 | ||
65 | /* | ||
66 | * The Hauppauge eeprom uses an 8bit field to determine which | ||
67 | * tuner formats the tuner supports. | ||
68 | */ | ||
70 | static struct HAUPPAUGE_TUNER_FMT | 69 | static struct HAUPPAUGE_TUNER_FMT |
71 | { | 70 | { |
72 | int id; | 71 | int id; |
@@ -74,14 +73,14 @@ static struct HAUPPAUGE_TUNER_FMT | |||
74 | } | 73 | } |
75 | hauppauge_tuner_fmt[] = | 74 | hauppauge_tuner_fmt[] = |
76 | { | 75 | { |
77 | { 0x00000000, " unknown1" }, | 76 | { V4L2_STD_UNKNOWN," UNKNOWN" }, |
78 | { 0x00000000, " unknown2" }, | 77 | { V4L2_STD_UNKNOWN," FM" }, |
79 | { 0x00000007, " PAL(B/G)" }, | 78 | { V4L2_STD_PAL_BG, " PAL(B/G)" }, |
80 | { 0x00001000, " NTSC(M)" }, | 79 | { V4L2_STD_NTSC_M, " NTSC(M)" }, |
81 | { 0x00000010, " PAL(I)" }, | 80 | { V4L2_STD_PAL_I, " PAL(I)" }, |
82 | { 0x00400000, " SECAM(L/L')" }, | 81 | { V4L2_STD_SECAM_L," SECAM(L/L')" }, |
83 | { 0x00000e00, " PAL(D/K)" }, | 82 | { V4L2_STD_PAL_DK, " PAL(D/D1/K)" }, |
84 | { 0x03000000, " ATSC/DVB Digital" }, | 83 | { V4L2_STD_ATSC, " ATSC/DVB Digital" }, |
85 | }; | 84 | }; |
86 | 85 | ||
87 | /* This is the full list of possible tuners. Many thanks to Hauppauge for | 86 | /* This is the full list of possible tuners. Many thanks to Hauppauge for |
@@ -387,7 +386,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
387 | if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) && | 386 | if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) && |
388 | (eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95)) | 387 | (eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95)) |
389 | start=0xa0; /* Generic em28xx offset */ | 388 | start=0xa0; /* Generic em28xx offset */ |
390 | else if (((eeprom_data[0] & 0xf0) == 0x10) && | 389 | else if (((eeprom_data[0] & 0xe1) == 0x01) && |
391 | (eeprom_data[1] == 0x00) && | 390 | (eeprom_data[1] == 0x00) && |
392 | (eeprom_data[2] == 0x00) && | 391 | (eeprom_data[2] == 0x00) && |
393 | (eeprom_data[8] == 0x84)) | 392 | (eeprom_data[8] == 0x84)) |
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index e837f9f7fed6..9e86caeb96a7 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c | |||
@@ -227,13 +227,9 @@ static int tvmixer_release(struct inode *inode, struct file *file) | |||
227 | } | 227 | } |
228 | 228 | ||
229 | static struct i2c_driver driver = { | 229 | static struct i2c_driver driver = { |
230 | #ifdef I2C_PEC | ||
231 | .driver = { | 230 | .driver = { |
232 | .name = "tv card mixer driver", | 231 | .name = "tvmixer", |
233 | }, | 232 | }, |
234 | #else | ||
235 | .name = "tv card mixer driver", | ||
236 | #endif | ||
237 | .id = I2C_DRIVERID_TVMIXER, | 233 | .id = I2C_DRIVERID_TVMIXER, |
238 | .detach_adapter = tvmixer_adapters, | 234 | .detach_adapter = tvmixer_adapters, |
239 | .attach_adapter = tvmixer_adapters, | 235 | .attach_adapter = tvmixer_adapters, |
@@ -267,22 +263,8 @@ static int tvmixer_clients(struct i2c_client *client) | |||
267 | struct video_audio va; | 263 | struct video_audio va; |
268 | int i,minor; | 264 | int i,minor; |
269 | 265 | ||
270 | #ifdef I2C_CLASS_TV_ANALOG | ||
271 | if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) | 266 | if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) |
272 | return -1; | 267 | return -1; |
273 | #else | ||
274 | /* TV card ??? */ | ||
275 | switch (client->adapter->id) { | ||
276 | case I2C_HW_SMBUS_VOODOO3: | ||
277 | case I2C_HW_B_BT848: | ||
278 | case I2C_HW_B_RIVA: | ||
279 | /* ok, have a look ... */ | ||
280 | break; | ||
281 | default: | ||
282 | /* ignore that one */ | ||
283 | return -1; | ||
284 | } | ||
285 | #endif | ||
286 | 268 | ||
287 | /* unregister ?? */ | 269 | /* unregister ?? */ |
288 | for (i = 0; i < DEV_MAX; i++) { | 270 | for (i = 0; i < DEV_MAX; i++) { |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index a60442ea4f94..c35b8042eee5 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/videodev.h> | 9 | #include <linux/videodev.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/video_decoder.h> | 11 | #include <linux/video_decoder.h> |
12 | #include <media/v4l2-common.h> | ||
12 | 13 | ||
13 | #include "tvp5150_reg.h" | 14 | #include "tvp5150_reg.h" |
14 | 15 | ||
@@ -28,33 +29,38 @@ static int debug = 0; | |||
28 | module_param(debug, int, 0); | 29 | module_param(debug, int, 0); |
29 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 30 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
30 | 31 | ||
31 | #define dprintk(num, format, args...) \ | 32 | #define tvp5150_info(fmt, arg...) do { \ |
33 | printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \ | ||
34 | i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) | ||
35 | #define tvp5150_dbg(num, fmt, arg...) \ | ||
32 | do { \ | 36 | do { \ |
33 | if (debug >= num) \ | 37 | if (debug >= num) \ |
34 | printk(format, ##args); \ | 38 | printk(KERN_DEBUG "%s debug %d-%04x: " fmt,\ |
35 | } while (0) | 39 | c->driver->driver.name, \ |
40 | i2c_adapter_id(c->adapter), \ | ||
41 | c->addr , ## arg); } while (0) | ||
36 | 42 | ||
37 | /* supported controls */ | 43 | /* supported controls */ |
38 | static struct v4l2_queryctrl tvp5150_qctrl[] = { | 44 | static struct v4l2_queryctrl tvp5150_qctrl[] = { |
39 | { | 45 | { |
40 | .id = V4L2_CID_BRIGHTNESS, | 46 | .id = V4L2_CID_BRIGHTNESS, |
41 | .type = V4L2_CTRL_TYPE_INTEGER, | 47 | .type = V4L2_CTRL_TYPE_INTEGER, |
42 | .name = "Brightness", | 48 | .name = "Brightness", |
43 | .minimum = 0, | 49 | .minimum = 0, |
44 | .maximum = 255, | 50 | .maximum = 255, |
45 | .step = 1, | 51 | .step = 1, |
46 | .default_value = 0, | 52 | .default_value = 0, |
47 | .flags = 0, | 53 | .flags = 0, |
48 | }, { | 54 | }, { |
49 | .id = V4L2_CID_CONTRAST, | 55 | .id = V4L2_CID_CONTRAST, |
50 | .type = V4L2_CTRL_TYPE_INTEGER, | 56 | .type = V4L2_CTRL_TYPE_INTEGER, |
51 | .name = "Contrast", | 57 | .name = "Contrast", |
52 | .minimum = 0, | 58 | .minimum = 0, |
53 | .maximum = 255, | 59 | .maximum = 255, |
54 | .step = 0x1, | 60 | .step = 0x1, |
55 | .default_value = 0x10, | 61 | .default_value = 0x10, |
56 | .flags = 0, | 62 | .flags = 0, |
57 | }, { | 63 | }, { |
58 | .id = V4L2_CID_SATURATION, | 64 | .id = V4L2_CID_SATURATION, |
59 | .type = V4L2_CTRL_TYPE_INTEGER, | 65 | .type = V4L2_CTRL_TYPE_INTEGER, |
60 | .name = "Saturation", | 66 | .name = "Saturation", |
@@ -63,16 +69,16 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { | |||
63 | .step = 0x1, | 69 | .step = 0x1, |
64 | .default_value = 0x10, | 70 | .default_value = 0x10, |
65 | .flags = 0, | 71 | .flags = 0, |
66 | }, { | 72 | }, { |
67 | .id = V4L2_CID_HUE, | 73 | .id = V4L2_CID_HUE, |
68 | .type = V4L2_CTRL_TYPE_INTEGER, | 74 | .type = V4L2_CTRL_TYPE_INTEGER, |
69 | .name = "Hue", | 75 | .name = "Hue", |
70 | .minimum = -128, | 76 | .minimum = -128, |
71 | .maximum = 127, | 77 | .maximum = 127, |
72 | .step = 0x1, | 78 | .step = 0x1, |
73 | .default_value = 0x10, | 79 | .default_value = 0x10, |
74 | .flags = 0, | 80 | .flags = 0, |
75 | } | 81 | } |
76 | }; | 82 | }; |
77 | 83 | ||
78 | struct tvp5150 { | 84 | struct tvp5150 { |
@@ -94,12 +100,14 @@ static inline int tvp5150_read(struct i2c_client *c, unsigned char addr) | |||
94 | 100 | ||
95 | buffer[0] = addr; | 101 | buffer[0] = addr; |
96 | if (1 != (rc = i2c_master_send(c, buffer, 1))) | 102 | if (1 != (rc = i2c_master_send(c, buffer, 1))) |
97 | dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); | 103 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); |
98 | 104 | ||
99 | msleep(10); | 105 | msleep(10); |
100 | 106 | ||
101 | if (1 != (rc = i2c_master_recv(c, buffer, 1))) | 107 | if (1 != (rc = i2c_master_recv(c, buffer, 1))) |
102 | dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); | 108 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); |
109 | |||
110 | tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); | ||
103 | 111 | ||
104 | return (buffer[0]); | 112 | return (buffer[0]); |
105 | } | 113 | } |
@@ -109,13 +117,12 @@ static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, | |||
109 | { | 117 | { |
110 | unsigned char buffer[2]; | 118 | unsigned char buffer[2]; |
111 | int rc; | 119 | int rc; |
112 | /* struct tvp5150 *core = i2c_get_clientdata(c); */ | ||
113 | 120 | ||
114 | buffer[0] = addr; | 121 | buffer[0] = addr; |
115 | buffer[1] = value; | 122 | buffer[1] = value; |
116 | dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); | 123 | tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); |
117 | if (2 != (rc = i2c_master_send(c, buffer, 2))) | 124 | if (2 != (rc = i2c_master_send(c, buffer, 2))) |
118 | dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc); | 125 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); |
119 | } | 126 | } |
120 | 127 | ||
121 | static void dump_reg(struct i2c_client *c) | 128 | static void dump_reg(struct i2c_client *c) |
@@ -437,48 +444,346 @@ enum tvp5150_input { | |||
437 | static inline void tvp5150_selmux(struct i2c_client *c, | 444 | static inline void tvp5150_selmux(struct i2c_client *c, |
438 | enum tvp5150_input input) | 445 | enum tvp5150_input input) |
439 | { | 446 | { |
447 | int opmode=0; | ||
448 | |||
440 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 449 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
441 | 450 | ||
442 | if (!decoder->enable) | 451 | if (!decoder->enable) |
443 | input |= TVP5150_BLACK_SCREEN; | 452 | input |= TVP5150_BLACK_SCREEN; |
444 | 453 | ||
454 | switch (input) { | ||
455 | case TVP5150_ANALOG_CH0: | ||
456 | case TVP5150_ANALOG_CH1: | ||
457 | opmode=0x30; /* TV Mode */ | ||
458 | break; | ||
459 | default: | ||
460 | opmode=0; /* Auto Mode */ | ||
461 | break; | ||
462 | } | ||
463 | |||
464 | tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode); | ||
445 | tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); | 465 | tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); |
446 | }; | 466 | }; |
447 | 467 | ||
448 | static inline void tvp5150_reset(struct i2c_client *c) | 468 | struct i2c_reg_value { |
469 | unsigned char reg; | ||
470 | unsigned char value; | ||
471 | }; | ||
472 | |||
473 | /* Default values as sugested at TVP5150AM1 datasheet */ | ||
474 | static const struct i2c_reg_value tvp5150_init_default[] = { | ||
475 | { /* 0x00 */ | ||
476 | TVP5150_VD_IN_SRC_SEL_1,0x00 | ||
477 | }, | ||
478 | { /* 0x01 */ | ||
479 | TVP5150_ANAL_CHL_CTL,0x15 | ||
480 | }, | ||
481 | { /* 0x02 */ | ||
482 | TVP5150_OP_MODE_CTL,0x00 | ||
483 | }, | ||
484 | { /* 0x03 */ | ||
485 | TVP5150_MISC_CTL,0x01 | ||
486 | }, | ||
487 | { /* 0x06 */ | ||
488 | TVP5150_COLOR_KIL_THSH_CTL,0x10 | ||
489 | }, | ||
490 | { /* 0x07 */ | ||
491 | TVP5150_LUMA_PROC_CTL_1,0x60 | ||
492 | }, | ||
493 | { /* 0x08 */ | ||
494 | TVP5150_LUMA_PROC_CTL_2,0x00 | ||
495 | }, | ||
496 | { /* 0x09 */ | ||
497 | TVP5150_BRIGHT_CTL,0x80 | ||
498 | }, | ||
499 | { /* 0x0a */ | ||
500 | TVP5150_SATURATION_CTL,0x80 | ||
501 | }, | ||
502 | { /* 0x0b */ | ||
503 | TVP5150_HUE_CTL,0x00 | ||
504 | }, | ||
505 | { /* 0x0c */ | ||
506 | TVP5150_CONTRAST_CTL,0x80 | ||
507 | }, | ||
508 | { /* 0x0d */ | ||
509 | TVP5150_DATA_RATE_SEL,0x47 | ||
510 | }, | ||
511 | { /* 0x0e */ | ||
512 | TVP5150_LUMA_PROC_CTL_3,0x00 | ||
513 | }, | ||
514 | { /* 0x0f */ | ||
515 | TVP5150_CONF_SHARED_PIN,0x08 | ||
516 | }, | ||
517 | { /* 0x11 */ | ||
518 | TVP5150_ACT_VD_CROP_ST_MSB,0x00 | ||
519 | }, | ||
520 | { /* 0x12 */ | ||
521 | TVP5150_ACT_VD_CROP_ST_LSB,0x00 | ||
522 | }, | ||
523 | { /* 0x13 */ | ||
524 | TVP5150_ACT_VD_CROP_STP_MSB,0x00 | ||
525 | }, | ||
526 | { /* 0x14 */ | ||
527 | TVP5150_ACT_VD_CROP_STP_LSB,0x00 | ||
528 | }, | ||
529 | { /* 0x15 */ | ||
530 | TVP5150_GENLOCK,0x01 | ||
531 | }, | ||
532 | { /* 0x16 */ | ||
533 | TVP5150_HORIZ_SYNC_START,0x80 | ||
534 | }, | ||
535 | { /* 0x18 */ | ||
536 | TVP5150_VERT_BLANKING_START,0x00 | ||
537 | }, | ||
538 | { /* 0x19 */ | ||
539 | TVP5150_VERT_BLANKING_STOP,0x00 | ||
540 | }, | ||
541 | { /* 0x1a */ | ||
542 | TVP5150_CHROMA_PROC_CTL_1,0x0c | ||
543 | }, | ||
544 | { /* 0x1b */ | ||
545 | TVP5150_CHROMA_PROC_CTL_2,0x14 | ||
546 | }, | ||
547 | { /* 0x1c */ | ||
548 | TVP5150_INT_RESET_REG_B,0x00 | ||
549 | }, | ||
550 | { /* 0x1d */ | ||
551 | TVP5150_INT_ENABLE_REG_B,0x00 | ||
552 | }, | ||
553 | { /* 0x1e */ | ||
554 | TVP5150_INTT_CONFIG_REG_B,0x00 | ||
555 | }, | ||
556 | { /* 0x28 */ | ||
557 | TVP5150_VIDEO_STD,0x00 | ||
558 | }, | ||
559 | { /* 0x2e */ | ||
560 | TVP5150_MACROVISION_ON_CTR,0x0f | ||
561 | }, | ||
562 | { /* 0x2f */ | ||
563 | TVP5150_MACROVISION_OFF_CTR,0x01 | ||
564 | }, | ||
565 | { /* 0xbb */ | ||
566 | TVP5150_TELETEXT_FIL_ENA,0x00 | ||
567 | }, | ||
568 | { /* 0xc0 */ | ||
569 | TVP5150_INT_STATUS_REG_A,0x00 | ||
570 | }, | ||
571 | { /* 0xc1 */ | ||
572 | TVP5150_INT_ENABLE_REG_A,0x00 | ||
573 | }, | ||
574 | { /* 0xc2 */ | ||
575 | TVP5150_INT_CONF,0x04 | ||
576 | }, | ||
577 | { /* 0xc8 */ | ||
578 | TVP5150_FIFO_INT_THRESHOLD,0x80 | ||
579 | }, | ||
580 | { /* 0xc9 */ | ||
581 | TVP5150_FIFO_RESET,0x00 | ||
582 | }, | ||
583 | { /* 0xca */ | ||
584 | TVP5150_LINE_NUMBER_INT,0x00 | ||
585 | }, | ||
586 | { /* 0xcb */ | ||
587 | TVP5150_PIX_ALIGN_REG_LOW,0x4e | ||
588 | }, | ||
589 | { /* 0xcc */ | ||
590 | TVP5150_PIX_ALIGN_REG_HIGH,0x00 | ||
591 | }, | ||
592 | { /* 0xcd */ | ||
593 | TVP5150_FIFO_OUT_CTRL,0x01 | ||
594 | }, | ||
595 | { /* 0xcf */ | ||
596 | TVP5150_FULL_FIELD_ENA_1,0x00 | ||
597 | }, | ||
598 | { /* 0xd0 */ | ||
599 | TVP5150_FULL_FIELD_ENA_2,0x00 | ||
600 | }, | ||
601 | { /* 0xfc */ | ||
602 | TVP5150_FULL_FIELD_MODE_REG,0x7f | ||
603 | }, | ||
604 | { /* end of data */ | ||
605 | 0xff,0xff | ||
606 | } | ||
607 | }; | ||
608 | |||
609 | /* Default values as sugested at TVP5150AM1 datasheet */ | ||
610 | static const struct i2c_reg_value tvp5150_init_enable[] = { | ||
611 | { | ||
612 | TVP5150_CONF_SHARED_PIN, 2 | ||
613 | },{ /* Automatic offset and AGC enabled */ | ||
614 | TVP5150_ANAL_CHL_CTL, 0x15 | ||
615 | },{ /* Activate YCrCb output 0x9 or 0xd ? */ | ||
616 | TVP5150_MISC_CTL, 0x6f | ||
617 | },{ /* Activates video std autodetection for all standards */ | ||
618 | TVP5150_AUTOSW_MSK, 0x0 | ||
619 | },{ /* Default format: 0x47. For 4:2:2: 0x40 */ | ||
620 | TVP5150_DATA_RATE_SEL, 0x47 | ||
621 | },{ | ||
622 | TVP5150_CHROMA_PROC_CTL_1, 0x0c | ||
623 | },{ | ||
624 | TVP5150_CHROMA_PROC_CTL_2, 0x54 | ||
625 | },{ /* Non documented, but initialized on WinTV USB2 */ | ||
626 | 0x27, 0x20 | ||
627 | },{ | ||
628 | 0xff,0xff | ||
629 | } | ||
630 | }; | ||
631 | |||
632 | struct i2c_vbi_ram_value { | ||
633 | u16 reg; | ||
634 | unsigned char values[26]; | ||
635 | }; | ||
636 | |||
637 | struct i2c_vbi_ram_value vbi_ram_default[] = | ||
449 | { | 638 | { |
450 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 639 | {0x010, /* WST SECAM 6 */ |
640 | { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 } | ||
641 | }, | ||
642 | {0x030, /* WST PAL B 6 */ | ||
643 | { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 } | ||
644 | }, | ||
645 | {0x050, /* WST PAL C 6 */ | ||
646 | { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } | ||
647 | }, | ||
648 | {0x070, /* WST NTSC 6 */ | ||
649 | { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } | ||
650 | }, | ||
651 | {0x090, /* NABTS, NTSC 6 */ | ||
652 | { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 } | ||
653 | }, | ||
654 | {0x0b0, /* NABTS, NTSC-J 6 */ | ||
655 | { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } | ||
656 | }, | ||
657 | {0x0d0, /* CC, PAL/SECAM 6 */ | ||
658 | { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } | ||
659 | }, | ||
660 | {0x0f0, /* CC, NTSC 6 */ | ||
661 | { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } | ||
662 | }, | ||
663 | {0x110, /* WSS, PAL/SECAM 6 */ | ||
664 | { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 } | ||
665 | }, | ||
666 | {0x130, /* WSS, NTSC C */ | ||
667 | { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 } | ||
668 | }, | ||
669 | {0x150, /* VITC, PAL/SECAM 6 */ | ||
670 | { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } | ||
671 | }, | ||
672 | {0x170, /* VITC, NTSC 6 */ | ||
673 | { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } | ||
674 | }, | ||
675 | { (u16)-1 } | ||
676 | }; | ||
451 | 677 | ||
452 | tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2); | 678 | static int tvp5150_write_inittab(struct i2c_client *c, |
679 | const struct i2c_reg_value *regs) | ||
680 | { | ||
681 | while (regs->reg != 0xff) { | ||
682 | tvp5150_write(c, regs->reg, regs->value); | ||
683 | regs++; | ||
684 | } | ||
685 | return 0; | ||
686 | } | ||
453 | 687 | ||
454 | /* Automatic offset and AGC enabled */ | 688 | static int tvp5150_vdp_init(struct i2c_client *c, |
455 | tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15); | 689 | const struct i2c_vbi_ram_value *regs) |
690 | { | ||
691 | unsigned int i; | ||
456 | 692 | ||
457 | /* Normal Operation */ | 693 | /* Disable Full Field */ |
458 | // tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00); | 694 | tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0); |
459 | 695 | ||
460 | /* Activate YCrCb output 0x9 or 0xd ? */ | 696 | /* Before programming, Line mode should be at 0xff */ |
461 | tvp5150_write(c, TVP5150_MISC_CTL, 0x6f); | 697 | for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++) |
698 | tvp5150_write(c, i, 0xff); | ||
462 | 699 | ||
463 | /* Activates video std autodetection for all standards */ | 700 | /* Load Ram Table */ |
464 | tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0); | 701 | while (regs->reg != (u16)-1 ) { |
702 | tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8); | ||
703 | tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg); | ||
465 | 704 | ||
466 | /* Default format: 0x47, 4:2:2: 0x40 */ | 705 | for (i=0;i<16;i++) |
467 | tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47); | 706 | tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]); |
468 | 707 | ||
469 | tvp5150_selmux(c, decoder->input); | 708 | regs++; |
709 | } | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) | ||
714 | { | ||
715 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
716 | int fmt=0; | ||
717 | |||
718 | decoder->norm=std; | ||
719 | |||
720 | /* First tests should be against specific std */ | ||
721 | |||
722 | if (std == V4L2_STD_ALL) { | ||
723 | fmt=0; /* Autodetect mode */ | ||
724 | } else if (std & V4L2_STD_NTSC_443) { | ||
725 | fmt=0xa; | ||
726 | } else if (std & V4L2_STD_PAL_M) { | ||
727 | fmt=0x6; | ||
728 | } else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) { | ||
729 | fmt=0x8; | ||
730 | } else { | ||
731 | /* Then, test against generic ones */ | ||
732 | if (std & V4L2_STD_NTSC) { | ||
733 | fmt=0x2; | ||
734 | } else if (std & V4L2_STD_PAL) { | ||
735 | fmt=0x4; | ||
736 | } else if (std & V4L2_STD_SECAM) { | ||
737 | fmt=0xc; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | tvp5150_dbg(1,"Set video std register to %d.\n",fmt); | ||
742 | tvp5150_write(c, TVP5150_VIDEO_STD, fmt); | ||
470 | 743 | ||
471 | tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c); | 744 | return 0; |
472 | tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54); | 745 | } |
473 | 746 | ||
474 | tvp5150_write(c, 0x27, 0x20); /* ?????????? */ | 747 | static inline void tvp5150_reset(struct i2c_client *c) |
748 | { | ||
749 | u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom; | ||
750 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
475 | 751 | ||
476 | tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */ | 752 | type=tvp5150_read(c,TVP5150_AUTOSW_MSK); |
753 | msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); | ||
754 | lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); | ||
755 | msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); | ||
756 | lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); | ||
757 | |||
758 | if (type==0xdc) { | ||
759 | ver_656=tvp5150_read(c,TVP5150_REV_SELECT); | ||
760 | tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656); | ||
761 | } else if (type==0xfc) { | ||
762 | tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); | ||
763 | } else { | ||
764 | tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type); | ||
765 | } | ||
766 | tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom); | ||
477 | 767 | ||
768 | /* Initializes TVP5150 to its default values */ | ||
769 | tvp5150_write_inittab(c, tvp5150_init_default); | ||
770 | |||
771 | /* Initializes VDP registers */ | ||
772 | tvp5150_vdp_init(c, vbi_ram_default); | ||
773 | |||
774 | /* Selects decoder input */ | ||
775 | tvp5150_selmux(c, decoder->input); | ||
776 | |||
777 | /* Initializes TVP5150 to stream enabled values */ | ||
778 | tvp5150_write_inittab(c, tvp5150_init_enable); | ||
779 | |||
780 | /* Initialize image preferences */ | ||
478 | tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8); | 781 | tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8); |
479 | tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8); | 782 | tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8); |
480 | tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8); | 783 | tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8); |
481 | tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8); | 784 | tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8); |
785 | |||
786 | tvp5150_set_std(c, decoder->norm); | ||
482 | }; | 787 | }; |
483 | 788 | ||
484 | static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | 789 | static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) |
@@ -498,9 +803,8 @@ static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | |||
498 | case V4L2_CID_HUE: | 803 | case V4L2_CID_HUE: |
499 | ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); | 804 | ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); |
500 | return 0; | 805 | return 0; |
501 | default: | ||
502 | return -EINVAL; | ||
503 | } | 806 | } |
807 | return -EINVAL; | ||
504 | } | 808 | } |
505 | 809 | ||
506 | static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | 810 | static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) |
@@ -520,28 +824,59 @@ static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | |||
520 | case V4L2_CID_HUE: | 824 | case V4L2_CID_HUE: |
521 | tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); | 825 | tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); |
522 | return 0; | 826 | return 0; |
523 | default: | ||
524 | return -EINVAL; | ||
525 | } | 827 | } |
828 | return -EINVAL; | ||
526 | } | 829 | } |
527 | 830 | ||
528 | /**************************************************************************** | 831 | /**************************************************************************** |
529 | I2C Command | 832 | I2C Command |
530 | ****************************************************************************/ | 833 | ****************************************************************************/ |
531 | static int tvp5150_command(struct i2c_client *client, | 834 | static int tvp5150_command(struct i2c_client *c, |
532 | unsigned int cmd, void *arg) | 835 | unsigned int cmd, void *arg) |
533 | { | 836 | { |
534 | struct tvp5150 *decoder = i2c_get_clientdata(client); | 837 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
535 | 838 | ||
536 | switch (cmd) { | 839 | switch (cmd) { |
537 | 840 | ||
538 | case 0: | 841 | case 0: |
842 | case VIDIOC_INT_RESET: | ||
539 | case DECODER_INIT: | 843 | case DECODER_INIT: |
540 | tvp5150_reset(client); | 844 | tvp5150_reset(c); |
845 | break; | ||
846 | case VIDIOC_S_STD: | ||
847 | if (decoder->norm == *(v4l2_std_id *)arg) | ||
848 | break; | ||
849 | return tvp5150_set_std(c, *(v4l2_std_id *)arg); | ||
850 | case VIDIOC_G_STD: | ||
851 | *(v4l2_std_id *)arg = decoder->norm; | ||
852 | break; | ||
853 | |||
854 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
855 | case VIDIOC_INT_G_REGISTER: | ||
856 | { | ||
857 | struct v4l2_register *reg = arg; | ||
858 | |||
859 | if (reg->i2c_id != I2C_DRIVERID_TVP5150) | ||
860 | return -EINVAL; | ||
861 | reg->val = tvp5150_read(c, reg->reg & 0xff); | ||
862 | break; | ||
863 | } | ||
864 | |||
865 | case VIDIOC_INT_S_REGISTER: | ||
866 | { | ||
867 | struct v4l2_register *reg = arg; | ||
868 | |||
869 | if (reg->i2c_id != I2C_DRIVERID_TVP5150) | ||
870 | return -EINVAL; | ||
871 | if (!capable(CAP_SYS_ADMIN)) | ||
872 | return -EPERM; | ||
873 | tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff); | ||
541 | break; | 874 | break; |
875 | } | ||
876 | #endif | ||
542 | 877 | ||
543 | case DECODER_DUMP: | 878 | case DECODER_DUMP: |
544 | dump_reg(client); | 879 | dump_reg(c); |
545 | break; | 880 | break; |
546 | 881 | ||
547 | case DECODER_GET_CAPABILITIES: | 882 | case DECODER_GET_CAPABILITIES: |
@@ -600,7 +935,7 @@ static int tvp5150_command(struct i2c_client *client, | |||
600 | } | 935 | } |
601 | 936 | ||
602 | decoder->input = *iarg; | 937 | decoder->input = *iarg; |
603 | tvp5150_selmux(client, decoder->input); | 938 | tvp5150_selmux(c, decoder->input); |
604 | 939 | ||
605 | break; | 940 | break; |
606 | } | 941 | } |
@@ -620,19 +955,18 @@ static int tvp5150_command(struct i2c_client *client, | |||
620 | 955 | ||
621 | decoder->enable = (*iarg != 0); | 956 | decoder->enable = (*iarg != 0); |
622 | 957 | ||
623 | tvp5150_selmux(client, decoder->input); | 958 | tvp5150_selmux(c, decoder->input); |
624 | 959 | ||
625 | break; | 960 | break; |
626 | } | 961 | } |
627 | case VIDIOC_QUERYCTRL: | 962 | case VIDIOC_QUERYCTRL: |
628 | { | 963 | { |
629 | struct v4l2_queryctrl *qc = arg; | 964 | struct v4l2_queryctrl *qc = arg; |
630 | u8 i, n; | 965 | int i; |
631 | 966 | ||
632 | dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL"); | 967 | tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n"); |
633 | 968 | ||
634 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); | 969 | for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) |
635 | for (i = 0; i < n; i++) | ||
636 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { | 970 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { |
637 | memcpy(qc, &(tvp5150_qctrl[i]), | 971 | memcpy(qc, &(tvp5150_qctrl[i]), |
638 | sizeof(*qc)); | 972 | sizeof(*qc)); |
@@ -644,16 +978,14 @@ static int tvp5150_command(struct i2c_client *client, | |||
644 | case VIDIOC_G_CTRL: | 978 | case VIDIOC_G_CTRL: |
645 | { | 979 | { |
646 | struct v4l2_control *ctrl = arg; | 980 | struct v4l2_control *ctrl = arg; |
647 | dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL"); | 981 | tvp5150_dbg(1, "VIDIOC_G_CTRL called\n"); |
648 | 982 | ||
649 | return tvp5150_get_ctrl(client, ctrl); | 983 | return tvp5150_get_ctrl(c, ctrl); |
650 | } | 984 | } |
651 | case VIDIOC_S_CTRL_OLD: /* ??? */ | ||
652 | case VIDIOC_S_CTRL: | 985 | case VIDIOC_S_CTRL: |
653 | { | 986 | { |
654 | struct v4l2_control *ctrl = arg; | 987 | struct v4l2_control *ctrl = arg; |
655 | u8 i, n; | 988 | u8 i, n; |
656 | dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL"); | ||
657 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); | 989 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); |
658 | for (i = 0; i < n; i++) | 990 | for (i = 0; i < n; i++) |
659 | if (ctrl->id == tvp5150_qctrl[i].id) { | 991 | if (ctrl->id == tvp5150_qctrl[i].id) { |
@@ -662,11 +994,10 @@ static int tvp5150_command(struct i2c_client *client, | |||
662 | || ctrl->value > | 994 | || ctrl->value > |
663 | tvp5150_qctrl[i].maximum) | 995 | tvp5150_qctrl[i].maximum) |
664 | return -ERANGE; | 996 | return -ERANGE; |
665 | dprintk(1, | 997 | tvp5150_dbg(1, |
666 | KERN_DEBUG | 998 | "VIDIOC_S_CTRL: id=%d, value=%d\n", |
667 | "VIDIOC_S_CTRL: id=%d, value=%d", | ||
668 | ctrl->id, ctrl->value); | 999 | ctrl->id, ctrl->value); |
669 | return tvp5150_set_ctrl(client, ctrl); | 1000 | return tvp5150_set_ctrl(c, ctrl); |
670 | } | 1001 | } |
671 | return -EINVAL; | 1002 | return -EINVAL; |
672 | } | 1003 | } |
@@ -677,25 +1008,25 @@ static int tvp5150_command(struct i2c_client *client, | |||
677 | if (decoder->bright != pic->brightness) { | 1008 | if (decoder->bright != pic->brightness) { |
678 | /* We want 0 to 255 we get 0-65535 */ | 1009 | /* We want 0 to 255 we get 0-65535 */ |
679 | decoder->bright = pic->brightness; | 1010 | decoder->bright = pic->brightness; |
680 | tvp5150_write(client, TVP5150_BRIGHT_CTL, | 1011 | tvp5150_write(c, TVP5150_BRIGHT_CTL, |
681 | decoder->bright >> 8); | 1012 | decoder->bright >> 8); |
682 | } | 1013 | } |
683 | if (decoder->contrast != pic->contrast) { | 1014 | if (decoder->contrast != pic->contrast) { |
684 | /* We want 0 to 255 we get 0-65535 */ | 1015 | /* We want 0 to 255 we get 0-65535 */ |
685 | decoder->contrast = pic->contrast; | 1016 | decoder->contrast = pic->contrast; |
686 | tvp5150_write(client, TVP5150_CONTRAST_CTL, | 1017 | tvp5150_write(c, TVP5150_CONTRAST_CTL, |
687 | decoder->contrast >> 8); | 1018 | decoder->contrast >> 8); |
688 | } | 1019 | } |
689 | if (decoder->sat != pic->colour) { | 1020 | if (decoder->sat != pic->colour) { |
690 | /* We want 0 to 255 we get 0-65535 */ | 1021 | /* We want 0 to 255 we get 0-65535 */ |
691 | decoder->sat = pic->colour; | 1022 | decoder->sat = pic->colour; |
692 | tvp5150_write(client, TVP5150_SATURATION_CTL, | 1023 | tvp5150_write(c, TVP5150_SATURATION_CTL, |
693 | decoder->contrast >> 8); | 1024 | decoder->contrast >> 8); |
694 | } | 1025 | } |
695 | if (decoder->hue != pic->hue) { | 1026 | if (decoder->hue != pic->hue) { |
696 | /* We want -128 to 127 we get 0-65535 */ | 1027 | /* We want -128 to 127 we get 0-65535 */ |
697 | decoder->hue = pic->hue; | 1028 | decoder->hue = pic->hue; |
698 | tvp5150_write(client, TVP5150_HUE_CTL, | 1029 | tvp5150_write(c, TVP5150_HUE_CTL, |
699 | (decoder->hue - 32768) >> 8); | 1030 | (decoder->hue - 32768) >> 8); |
700 | } | 1031 | } |
701 | break; | 1032 | break; |
@@ -720,12 +1051,12 @@ static struct i2c_client client_template = { | |||
720 | static int tvp5150_detect_client(struct i2c_adapter *adapter, | 1051 | static int tvp5150_detect_client(struct i2c_adapter *adapter, |
721 | int address, int kind) | 1052 | int address, int kind) |
722 | { | 1053 | { |
723 | struct i2c_client *client; | 1054 | struct i2c_client *c; |
724 | struct tvp5150 *core; | 1055 | struct tvp5150 *core; |
725 | int rv; | 1056 | int rv; |
726 | 1057 | ||
727 | dprintk(1, | 1058 | if (debug) |
728 | KERN_INFO | 1059 | printk( KERN_INFO |
729 | "tvp5150.c: detecting tvp5150 client on address 0x%x\n", | 1060 | "tvp5150.c: detecting tvp5150 client on address 0x%x\n", |
730 | address << 1); | 1061 | address << 1); |
731 | 1062 | ||
@@ -738,22 +1069,22 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, | |||
738 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 1069 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) |
739 | return 0; | 1070 | return 0; |
740 | 1071 | ||
741 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | 1072 | c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); |
742 | if (client == 0) | 1073 | if (c == 0) |
743 | return -ENOMEM; | 1074 | return -ENOMEM; |
744 | memcpy(client, &client_template, sizeof(struct i2c_client)); | 1075 | memcpy(c, &client_template, sizeof(struct i2c_client)); |
745 | 1076 | ||
746 | core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL); | 1077 | core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL); |
747 | if (core == 0) { | 1078 | if (core == 0) { |
748 | kfree(client); | 1079 | kfree(c); |
749 | return -ENOMEM; | 1080 | return -ENOMEM; |
750 | } | 1081 | } |
751 | memset(core, 0, sizeof(struct tvp5150)); | 1082 | memset(core, 0, sizeof(struct tvp5150)); |
752 | i2c_set_clientdata(client, core); | 1083 | i2c_set_clientdata(c, core); |
753 | 1084 | ||
754 | rv = i2c_attach_client(client); | 1085 | rv = i2c_attach_client(c); |
755 | 1086 | ||
756 | core->norm = VIDEO_MODE_AUTO; | 1087 | core->norm = V4L2_STD_ALL; |
757 | core->input = 2; | 1088 | core->input = 2; |
758 | core->enable = 1; | 1089 | core->enable = 1; |
759 | core->bright = 32768; | 1090 | core->bright = 32768; |
@@ -762,37 +1093,41 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, | |||
762 | core->sat = 32768; | 1093 | core->sat = 32768; |
763 | 1094 | ||
764 | if (rv) { | 1095 | if (rv) { |
765 | kfree(client); | 1096 | kfree(c); |
766 | kfree(core); | 1097 | kfree(core); |
767 | return rv; | 1098 | return rv; |
768 | } | 1099 | } |
769 | 1100 | ||
770 | if (debug > 1) | 1101 | if (debug > 1) |
771 | dump_reg(client); | 1102 | dump_reg(c); |
772 | return 0; | 1103 | return 0; |
773 | } | 1104 | } |
774 | 1105 | ||
775 | static int tvp5150_attach_adapter(struct i2c_adapter *adapter) | 1106 | static int tvp5150_attach_adapter(struct i2c_adapter *adapter) |
776 | { | 1107 | { |
777 | dprintk(1, | 1108 | if (debug) |
778 | KERN_INFO | 1109 | printk( KERN_INFO |
779 | "tvp5150.c: starting probe for adapter %s (0x%x)\n", | 1110 | "tvp5150.c: starting probe for adapter %s (0x%x)\n", |
780 | adapter->name, adapter->id); | 1111 | adapter->name, adapter->id); |
781 | return i2c_probe(adapter, &addr_data, &tvp5150_detect_client); | 1112 | return i2c_probe(adapter, &addr_data, &tvp5150_detect_client); |
782 | } | 1113 | } |
783 | 1114 | ||
784 | static int tvp5150_detach_client(struct i2c_client *client) | 1115 | static int tvp5150_detach_client(struct i2c_client *c) |
785 | { | 1116 | { |
786 | struct tvp5150 *decoder = i2c_get_clientdata(client); | 1117 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
787 | int err; | 1118 | int err; |
788 | 1119 | ||
789 | err = i2c_detach_client(client); | 1120 | tvp5150_dbg(1, |
1121 | "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", | ||
1122 | c->addr << 1); | ||
1123 | |||
1124 | err = i2c_detach_client(c); | ||
790 | if (err) { | 1125 | if (err) { |
791 | return err; | 1126 | return err; |
792 | } | 1127 | } |
793 | 1128 | ||
794 | kfree(decoder); | 1129 | kfree(decoder); |
795 | kfree(client); | 1130 | kfree(c); |
796 | 1131 | ||
797 | return 0; | 1132 | return 0; |
798 | } | 1133 | } |
@@ -803,9 +1138,7 @@ static struct i2c_driver driver = { | |||
803 | .driver = { | 1138 | .driver = { |
804 | .name = "tvp5150", | 1139 | .name = "tvp5150", |
805 | }, | 1140 | }, |
806 | 1141 | .id = I2C_DRIVERID_TVP5150, | |
807 | /* FIXME */ | ||
808 | .id = I2C_DRIVERID_SAA7110, | ||
809 | 1142 | ||
810 | .attach_adapter = tvp5150_attach_adapter, | 1143 | .attach_adapter = tvp5150_attach_adapter, |
811 | .detach_client = tvp5150_detach_client, | 1144 | .detach_client = tvp5150_detach_client, |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index 4134549d11a8..2ab5b4093800 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -951,6 +951,10 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
951 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); | 951 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); |
952 | break; | 952 | break; |
953 | } | 953 | } |
954 | if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { | ||
955 | err = -EINVAL; | ||
956 | break; | ||
957 | } | ||
954 | memset(fmt, 0, sizeof(*fmt)); | 958 | memset(fmt, 0, sizeof(*fmt)); |
955 | fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; | 959 | fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; |
956 | fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; | 960 | fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; |
@@ -966,6 +970,11 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
966 | { | 970 | { |
967 | struct vbi_format *fmt = arg; | 971 | struct vbi_format *fmt = arg; |
968 | 972 | ||
973 | if (VIDEO_PALETTE_RAW != fmt->sample_format) { | ||
974 | err = -EINVAL; | ||
975 | break; | ||
976 | } | ||
977 | |||
969 | fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); | 978 | fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); |
970 | memset(fmt2, 0, sizeof(*fmt2)); | 979 | memset(fmt2, 0, sizeof(*fmt2)); |
971 | 980 | ||
@@ -986,7 +995,7 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
986 | 995 | ||
987 | if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || | 996 | if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || |
988 | fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || | 997 | fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || |
989 | VIDEO_PALETTE_RAW != fmt->sample_format || | 998 | fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY || |
990 | fmt2->fmt.vbi.start[0] != fmt->start[0] || | 999 | fmt2->fmt.vbi.start[0] != fmt->start[0] || |
991 | fmt2->fmt.vbi.count[0] != fmt->count[0] || | 1000 | fmt2->fmt.vbi.count[0] != fmt->count[0] || |
992 | fmt2->fmt.vbi.start[1] != fmt->start[1] || | 1001 | fmt2->fmt.vbi.start[1] != fmt->start[1] || |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 62a7d636ef11..5dbd7c1b362a 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -58,6 +58,8 @@ | |||
58 | #include <asm/pgtable.h> | 58 | #include <asm/pgtable.h> |
59 | #include <asm/io.h> | 59 | #include <asm/io.h> |
60 | #include <asm/div64.h> | 60 | #include <asm/div64.h> |
61 | #include <linux/video_decoder.h> | ||
62 | #include <media/v4l2-common.h> | ||
61 | 63 | ||
62 | #ifdef CONFIG_KMOD | 64 | #ifdef CONFIG_KMOD |
63 | #include <linux/kmod.h> | 65 | #include <linux/kmod.h> |
@@ -190,55 +192,174 @@ char *v4l2_type_names[] = { | |||
190 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", | 192 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", |
191 | }; | 193 | }; |
192 | 194 | ||
193 | char *v4l2_ioctl_names[256] = { | 195 | /* ------------------------------------------------------------------ */ |
194 | [0 ... 255] = "UNKNOWN", | 196 | /* debug help functions */ |
195 | [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", | 197 | |
196 | [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", | 198 | #ifdef HAVE_V4L1 |
197 | [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", | 199 | static const char *v4l1_ioctls[] = { |
198 | [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", | 200 | [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", |
199 | [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", | 201 | [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", |
200 | [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", | 202 | [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", |
201 | [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", | 203 | [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", |
202 | [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", | 204 | [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", |
203 | [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", | 205 | [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", |
204 | [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", | 206 | [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", |
205 | [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", | 207 | [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", |
206 | [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", | 208 | [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", |
207 | [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", | 209 | [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", |
208 | [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", | 210 | [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", |
209 | [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", | 211 | [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", |
210 | [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", | 212 | [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", |
211 | [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", | 213 | [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", |
212 | [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", | 214 | [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", |
213 | [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", | 215 | [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", |
214 | [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", | 216 | [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", |
215 | [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", | 217 | [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", |
216 | [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", | 218 | [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", |
217 | [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", | 219 | [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", |
218 | [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", | 220 | [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", |
219 | [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", | 221 | [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", |
220 | [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", | 222 | [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", |
221 | [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", | 223 | [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", |
222 | [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", | 224 | [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", |
223 | [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", | 225 | [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", |
224 | [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", | 226 | [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", |
225 | [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", | 227 | [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", |
226 | [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", | 228 | [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" |
227 | [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", | ||
228 | [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", | ||
229 | [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", | ||
230 | [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", | ||
231 | [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", | ||
232 | [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", | ||
233 | [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", | ||
234 | [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", | ||
235 | [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", | ||
236 | [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", | ||
237 | [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", | ||
238 | [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", | ||
239 | [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", | ||
240 | [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", | ||
241 | }; | 229 | }; |
230 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
231 | #endif | ||
232 | |||
233 | static const char *v4l2_ioctls[] = { | ||
234 | [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", | ||
235 | [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", | ||
236 | [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", | ||
237 | [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", | ||
238 | [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", | ||
239 | [_IOC_NR(VIDIOC_G_MPEGCOMP)] = "VIDIOC_G_MPEGCOMP", | ||
240 | [_IOC_NR(VIDIOC_S_MPEGCOMP)] = "VIDIOC_S_MPEGCOMP", | ||
241 | [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", | ||
242 | [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", | ||
243 | [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", | ||
244 | [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", | ||
245 | [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", | ||
246 | [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", | ||
247 | [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", | ||
248 | [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", | ||
249 | [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", | ||
250 | [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", | ||
251 | [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", | ||
252 | [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", | ||
253 | [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", | ||
254 | [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", | ||
255 | [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", | ||
256 | [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", | ||
257 | [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", | ||
258 | [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", | ||
259 | [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", | ||
260 | [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", | ||
261 | [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", | ||
262 | [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", | ||
263 | [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", | ||
264 | [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", | ||
265 | [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", | ||
266 | [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", | ||
267 | [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", | ||
268 | [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", | ||
269 | [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", | ||
270 | [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", | ||
271 | [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", | ||
272 | [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", | ||
273 | [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", | ||
274 | [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", | ||
275 | [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", | ||
276 | [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", | ||
277 | [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", | ||
278 | [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", | ||
279 | [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", | ||
280 | [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", | ||
281 | [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", | ||
282 | [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", | ||
283 | [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", | ||
284 | [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", | ||
285 | [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", | ||
286 | #if 1 | ||
287 | [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", | ||
288 | #endif | ||
289 | [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS" | ||
290 | }; | ||
291 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | ||
292 | |||
293 | static const char *v4l2_int_ioctls[] = { | ||
294 | #ifdef HAVE_VIDEO_DECODER | ||
295 | [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", | ||
296 | [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", | ||
297 | [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", | ||
298 | [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", | ||
299 | [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", | ||
300 | [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", | ||
301 | [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", | ||
302 | [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", | ||
303 | [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", | ||
304 | [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", | ||
305 | [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", | ||
306 | #endif | ||
307 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", | ||
308 | [_IOC_NR(AUDC_SET_INPUT)] = "AUDC_SET_INPUT", | ||
309 | |||
310 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", | ||
311 | [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", | ||
312 | [_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG", | ||
313 | |||
314 | [_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER", | ||
315 | [_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER", | ||
316 | [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", | ||
317 | [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", | ||
318 | [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", | ||
319 | [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", | ||
320 | [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", | ||
321 | [_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT", | ||
322 | [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ" | ||
323 | }; | ||
324 | #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) | ||
325 | |||
326 | /* Common ioctl debug function. This function can be used by | ||
327 | external ioctl messages as well as internal V4L ioctl */ | ||
328 | void v4l_printk_ioctl(unsigned int cmd) | ||
329 | { | ||
330 | char *dir; | ||
331 | |||
332 | switch (_IOC_DIR(cmd)) { | ||
333 | case _IOC_NONE: dir = "--"; break; | ||
334 | case _IOC_READ: dir = "r-"; break; | ||
335 | case _IOC_WRITE: dir = "-w"; break; | ||
336 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
337 | default: dir = "*ERR*"; break; | ||
338 | } | ||
339 | switch (_IOC_TYPE(cmd)) { | ||
340 | case 'd': | ||
341 | printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", | ||
342 | (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? | ||
343 | v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | ||
344 | break; | ||
345 | #ifdef HAVE_V4L1 | ||
346 | case 'v': | ||
347 | printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", | ||
348 | (_IOC_NR(cmd) < V4L1_IOCTLS) ? | ||
349 | v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | ||
350 | break; | ||
351 | #endif | ||
352 | case 'V': | ||
353 | printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", | ||
354 | (_IOC_NR(cmd) < V4L2_IOCTLS) ? | ||
355 | v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | ||
356 | break; | ||
357 | |||
358 | default: | ||
359 | printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", | ||
360 | _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); | ||
361 | } | ||
362 | } | ||
242 | 363 | ||
243 | /* ----------------------------------------------------------------- */ | 364 | /* ----------------------------------------------------------------- */ |
244 | 365 | ||
@@ -253,7 +374,7 @@ EXPORT_SYMBOL(v4l2_prio_check); | |||
253 | 374 | ||
254 | EXPORT_SYMBOL(v4l2_field_names); | 375 | EXPORT_SYMBOL(v4l2_field_names); |
255 | EXPORT_SYMBOL(v4l2_type_names); | 376 | EXPORT_SYMBOL(v4l2_type_names); |
256 | EXPORT_SYMBOL(v4l2_ioctl_names); | 377 | EXPORT_SYMBOL(v4l_printk_ioctl); |
257 | 378 | ||
258 | /* | 379 | /* |
259 | * Local variables: | 380 | * Local variables: |
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 6de5b0094b82..9a9902c56ae7 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -68,7 +68,8 @@ static void video_release(struct class_device *cd) | |||
68 | { | 68 | { |
69 | struct video_device *vfd = container_of(cd, struct video_device, class_dev); | 69 | struct video_device *vfd = container_of(cd, struct video_device, class_dev); |
70 | 70 | ||
71 | #if 1 /* needed until all drivers are fixed */ | 71 | #if 1 |
72 | /* needed until all drivers are fixed */ | ||
72 | if (!vfd->release) | 73 | if (!vfd->release) |
73 | return; | 74 | return; |
74 | #endif | 75 | #endif |
@@ -338,13 +339,14 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
338 | if (vfd->dev) | 339 | if (vfd->dev) |
339 | vfd->class_dev.dev = vfd->dev; | 340 | vfd->class_dev.dev = vfd->dev; |
340 | vfd->class_dev.class = &video_class; | 341 | vfd->class_dev.class = &video_class; |
341 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); | 342 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); |
342 | strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE); | 343 | strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE); |
343 | class_device_register(&vfd->class_dev); | 344 | class_device_register(&vfd->class_dev); |
344 | class_device_create_file(&vfd->class_dev, | 345 | class_device_create_file(&vfd->class_dev, |
345 | &class_device_attr_name); | 346 | &class_device_attr_name); |
346 | 347 | ||
347 | #if 1 /* needed until all drivers are fixed */ | 348 | #if 1 |
349 | /* needed until all drivers are fixed */ | ||
348 | if (!vfd->release) | 350 | if (!vfd->release) |
349 | printk(KERN_WARNING "videodev: \"%s\" has no release callback. " | 351 | printk(KERN_WARNING "videodev: \"%s\" has no release callback. " |
350 | "Please fix your driver for proper sysfs support, see " | 352 | "Please fix your driver for proper sysfs support, see " |
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index c318ba32fbaf..b7b0afffd214 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
@@ -187,6 +187,7 @@ static struct file_operations w9966_fops = { | |||
187 | .open = video_exclusive_open, | 187 | .open = video_exclusive_open, |
188 | .release = video_exclusive_release, | 188 | .release = video_exclusive_release, |
189 | .ioctl = w9966_v4l_ioctl, | 189 | .ioctl = w9966_v4l_ioctl, |
190 | .compat_ioctl = v4l_compat_ioctl32, | ||
190 | .read = w9966_v4l_read, | 191 | .read = w9966_v4l_read, |
191 | .llseek = no_llseek, | 192 | .llseek = no_llseek, |
192 | }; | 193 | }; |
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index bbfd55cd9948..c2e6d2e9f5f1 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c | |||
@@ -25,7 +25,6 @@ | |||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | |||
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/types.h> | 29 | #include <linux/types.h> |
31 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
@@ -33,20 +32,12 @@ | |||
33 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
34 | #include <linux/i2c-id.h> | 33 | #include <linux/i2c-id.h> |
35 | #include <linux/videodev.h> | 34 | #include <linux/videodev.h> |
36 | #include <media/audiochip.h> | 35 | #include <media/v4l2-common.h> |
37 | 36 | ||
38 | MODULE_DESCRIPTION("wm8775 driver"); | 37 | MODULE_DESCRIPTION("wm8775 driver"); |
39 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); | 38 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); |
40 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
41 | 40 | ||
42 | #define wm8775_err(fmt, arg...) do { \ | ||
43 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
44 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
45 | #define wm8775_info(fmt, arg...) do { \ | ||
46 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | ||
47 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
48 | |||
49 | |||
50 | static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; | 41 | static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; |
51 | 42 | ||
52 | 43 | ||
@@ -70,7 +61,7 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val) | |||
70 | int i; | 61 | int i; |
71 | 62 | ||
72 | if (reg < 0 || reg >= TOT_REGS) { | 63 | if (reg < 0 || reg >= TOT_REGS) { |
73 | wm8775_err("Invalid register R%d\n", reg); | 64 | v4l_err(client, "Invalid register R%d\n", reg); |
74 | return -1; | 65 | return -1; |
75 | } | 66 | } |
76 | 67 | ||
@@ -80,7 +71,7 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val) | |||
80 | return 0; | 71 | return 0; |
81 | } | 72 | } |
82 | } | 73 | } |
83 | wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg); | 74 | v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); |
84 | return -1; | 75 | return -1; |
85 | } | 76 | } |
86 | 77 | ||
@@ -88,38 +79,53 @@ static int wm8775_command(struct i2c_client *client, unsigned int cmd, | |||
88 | void *arg) | 79 | void *arg) |
89 | { | 80 | { |
90 | struct wm8775_state *state = i2c_get_clientdata(client); | 81 | struct wm8775_state *state = i2c_get_clientdata(client); |
91 | int *input = arg; | 82 | struct v4l2_audio *input = arg; |
83 | struct v4l2_control *ctrl = arg; | ||
92 | 84 | ||
93 | switch (cmd) { | 85 | switch (cmd) { |
94 | case AUDC_SET_INPUT: | 86 | case VIDIOC_S_AUDIO: |
87 | /* There are 4 inputs and one output. Zero or more inputs | ||
88 | are multiplexed together to the output. Hence there are | ||
89 | 16 combinations. | ||
90 | If only one input is active (the normal case) then the | ||
91 | input values 1, 2, 4 or 8 should be used. */ | ||
92 | if (input->index > 15) { | ||
93 | v4l_err(client, "Invalid input %d.\n", input->index); | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | state->input = input->index; | ||
97 | if (state->muted) | ||
98 | break; | ||
95 | wm8775_write(client, R21, 0x0c0); | 99 | wm8775_write(client, R21, 0x0c0); |
96 | wm8775_write(client, R14, 0x1d4); | 100 | wm8775_write(client, R14, 0x1d4); |
97 | wm8775_write(client, R15, 0x1d4); | 101 | wm8775_write(client, R15, 0x1d4); |
102 | wm8775_write(client, R21, 0x100 + state->input); | ||
103 | break; | ||
98 | 104 | ||
99 | if (*input == AUDIO_RADIO) { | 105 | case VIDIOC_G_AUDIO: |
100 | wm8775_write(client, R21, 0x108); | 106 | memset(input, 0, sizeof(*input)); |
101 | state->input = 8; | 107 | input->index = state->input; |
102 | state->muted = 0; | 108 | break; |
103 | break; | 109 | |
104 | } | 110 | case VIDIOC_G_CTRL: |
105 | if (*input == AUDIO_MUTE) { | 111 | if (ctrl->id != V4L2_CID_AUDIO_MUTE) |
106 | state->muted = 1; | 112 | return -EINVAL; |
107 | break; | 113 | ctrl->value = state->muted; |
108 | } | 114 | break; |
109 | if (*input == AUDIO_UNMUTE) { | 115 | |
116 | case VIDIOC_S_CTRL: | ||
117 | if (ctrl->id != V4L2_CID_AUDIO_MUTE) | ||
118 | return -EINVAL; | ||
119 | state->muted = ctrl->value; | ||
120 | wm8775_write(client, R21, 0x0c0); | ||
121 | wm8775_write(client, R14, 0x1d4); | ||
122 | wm8775_write(client, R15, 0x1d4); | ||
123 | if (!state->muted) | ||
110 | wm8775_write(client, R21, 0x100 + state->input); | 124 | wm8775_write(client, R21, 0x100 + state->input); |
111 | state->muted = 0; | ||
112 | break; | ||
113 | } | ||
114 | /* All other inputs... */ | ||
115 | wm8775_write(client, R21, 0x102); | ||
116 | state->input = 2; | ||
117 | state->muted = 0; | ||
118 | break; | 125 | break; |
119 | 126 | ||
120 | case VIDIOC_LOG_STATUS: | 127 | case VIDIOC_LOG_STATUS: |
121 | wm8775_info("Input: %s%s\n", | 128 | v4l_info(client, "Input: %d%s\n", state->input, |
122 | state->input == 8 ? "radio" : "default", | ||
123 | state->muted ? " (muted)" : ""); | 129 | state->muted ? " (muted)" : ""); |
124 | break; | 130 | break; |
125 | 131 | ||
@@ -170,7 +176,7 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind) | |||
170 | client->driver = &i2c_driver; | 176 | client->driver = &i2c_driver; |
171 | snprintf(client->name, sizeof(client->name) - 1, "wm8775"); | 177 | snprintf(client->name, sizeof(client->name) - 1, "wm8775"); |
172 | 178 | ||
173 | wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); | 179 | v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); |
174 | 180 | ||
175 | state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL); | 181 | state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL); |
176 | if (state == NULL) { | 182 | if (state == NULL) { |
@@ -206,11 +212,7 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind) | |||
206 | 212 | ||
207 | static int wm8775_probe(struct i2c_adapter *adapter) | 213 | static int wm8775_probe(struct i2c_adapter *adapter) |
208 | { | 214 | { |
209 | #ifdef I2C_CLASS_TV_ANALOG | ||
210 | if (adapter->class & I2C_CLASS_TV_ANALOG) | 215 | if (adapter->class & I2C_CLASS_TV_ANALOG) |
211 | #else | ||
212 | if (adapter->id == I2C_HW_B_BT848) | ||
213 | #endif | ||
214 | return i2c_probe(adapter, &addr_data, wm8775_attach); | 216 | return i2c_probe(adapter, &addr_data, wm8775_attach); |
215 | return 0; | 217 | return 0; |
216 | } | 218 | } |
@@ -235,12 +237,10 @@ static struct i2c_driver i2c_driver = { | |||
235 | .driver = { | 237 | .driver = { |
236 | .name = "wm8775", | 238 | .name = "wm8775", |
237 | }, | 239 | }, |
238 | 240 | .id = I2C_DRIVERID_WM8775, | |
239 | .id = I2C_DRIVERID_WM8775, | ||
240 | |||
241 | .attach_adapter = wm8775_probe, | 241 | .attach_adapter = wm8775_probe, |
242 | .detach_client = wm8775_detach, | 242 | .detach_client = wm8775_detach, |
243 | .command = wm8775_command, | 243 | .command = wm8775_command, |
244 | }; | 244 | }; |
245 | 245 | ||
246 | 246 | ||
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 4034f1b45366..15283f44e79f 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -4678,6 +4678,7 @@ static struct file_operations zoran_fops = { | |||
4678 | .open = zoran_open, | 4678 | .open = zoran_open, |
4679 | .release = zoran_close, | 4679 | .release = zoran_close, |
4680 | .ioctl = zoran_ioctl, | 4680 | .ioctl = zoran_ioctl, |
4681 | .compat_ioctl = v4l_compat_ioctl32, | ||
4681 | .llseek = no_llseek, | 4682 | .llseek = no_llseek, |
4682 | .read = zoran_read, | 4683 | .read = zoran_read, |
4683 | .write = zoran_write, | 4684 | .write = zoran_write, |
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c index 07286816d7df..d4c633b8a7f5 100644 --- a/drivers/media/video/zr36120.c +++ b/drivers/media/video/zr36120.c | |||
@@ -1490,6 +1490,7 @@ static struct video_device zr36120_template= | |||
1490 | .write = zoran_write, | 1490 | .write = zoran_write, |
1491 | .poll = zoran_poll, | 1491 | .poll = zoran_poll, |
1492 | .ioctl = zoran_ioctl, | 1492 | .ioctl = zoran_ioctl, |
1493 | .compat_ioctl = v4l_compat_ioctl32, | ||
1493 | .mmap = zoran_mmap, | 1494 | .mmap = zoran_mmap, |
1494 | .minor = -1, | 1495 | .minor = -1, |
1495 | }; | 1496 | }; |
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c index 6a5700e9d428..25646804d5be 100644 --- a/drivers/usb/media/dsbr100.c +++ b/drivers/usb/media/dsbr100.c | |||
@@ -127,6 +127,7 @@ static struct file_operations usb_dsbr100_fops = { | |||
127 | .open = usb_dsbr100_open, | 127 | .open = usb_dsbr100_open, |
128 | .release = usb_dsbr100_close, | 128 | .release = usb_dsbr100_close, |
129 | .ioctl = usb_dsbr100_ioctl, | 129 | .ioctl = usb_dsbr100_ioctl, |
130 | .compat_ioctl = v4l_compat_ioctl32, | ||
130 | .llseek = no_llseek, | 131 | .llseek = no_llseek, |
131 | }; | 132 | }; |
132 | 133 | ||
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 3a0e8ce67ebe..8af665bbe330 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c | |||
@@ -4774,6 +4774,7 @@ static struct file_operations ov511_fops = { | |||
4774 | .read = ov51x_v4l1_read, | 4774 | .read = ov51x_v4l1_read, |
4775 | .mmap = ov51x_v4l1_mmap, | 4775 | .mmap = ov51x_v4l1_mmap, |
4776 | .ioctl = ov51x_v4l1_ioctl, | 4776 | .ioctl = ov51x_v4l1_ioctl, |
4777 | .compat_ioctl = v4l_compat_ioctl32, | ||
4777 | .llseek = no_llseek, | 4778 | .llseek = no_llseek, |
4778 | }; | 4779 | }; |
4779 | 4780 | ||
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 09ca6128ac20..4f9b0dc6fd7b 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c | |||
@@ -154,6 +154,7 @@ static struct file_operations pwc_fops = { | |||
154 | .poll = pwc_video_poll, | 154 | .poll = pwc_video_poll, |
155 | .mmap = pwc_video_mmap, | 155 | .mmap = pwc_video_mmap, |
156 | .ioctl = pwc_video_ioctl, | 156 | .ioctl = pwc_video_ioctl, |
157 | .compat_ioctl = v4l_compat_ioctl32, | ||
157 | .llseek = no_llseek, | 158 | .llseek = no_llseek, |
158 | }; | 159 | }; |
159 | static struct video_device pwc_template = { | 160 | static struct video_device pwc_template = { |
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index b2ae29af5940..2ba562285fda 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c | |||
@@ -1193,6 +1193,7 @@ static struct file_operations se401_fops = { | |||
1193 | .read = se401_read, | 1193 | .read = se401_read, |
1194 | .mmap = se401_mmap, | 1194 | .mmap = se401_mmap, |
1195 | .ioctl = se401_ioctl, | 1195 | .ioctl = se401_ioctl, |
1196 | .compat_ioctl = v4l_compat_ioctl32, | ||
1196 | .llseek = no_llseek, | 1197 | .llseek = no_llseek, |
1197 | }; | 1198 | }; |
1198 | static struct video_device se401_template = { | 1199 | static struct video_device se401_template = { |
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index 774038b352cd..b497a6a0a206 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c | |||
@@ -1343,6 +1343,7 @@ static struct file_operations stv680_fops = { | |||
1343 | .read = stv680_read, | 1343 | .read = stv680_read, |
1344 | .mmap = stv680_mmap, | 1344 | .mmap = stv680_mmap, |
1345 | .ioctl = stv680_ioctl, | 1345 | .ioctl = stv680_ioctl, |
1346 | .compat_ioctl = v4l_compat_ioctl32, | ||
1346 | .llseek = no_llseek, | 1347 | .llseek = no_llseek, |
1347 | }; | 1348 | }; |
1348 | static struct video_device stv680_template = { | 1349 | static struct video_device stv680_template = { |
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index 4bd113325ef9..63a72e550a1b 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c | |||
@@ -953,6 +953,7 @@ static struct file_operations usbvideo_fops = { | |||
953 | .read = usbvideo_v4l_read, | 953 | .read = usbvideo_v4l_read, |
954 | .mmap = usbvideo_v4l_mmap, | 954 | .mmap = usbvideo_v4l_mmap, |
955 | .ioctl = usbvideo_v4l_ioctl, | 955 | .ioctl = usbvideo_v4l_ioctl, |
956 | .compat_ioctl = v4l_compat_ioctl32, | ||
956 | .llseek = no_llseek, | 957 | .llseek = no_llseek, |
957 | }; | 958 | }; |
958 | static const struct video_device usbvideo_template = { | 959 | static const struct video_device usbvideo_template = { |
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 1c73155c8d77..5df144073871 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c | |||
@@ -1236,6 +1236,7 @@ static struct file_operations vicam_fops = { | |||
1236 | .read = vicam_read, | 1236 | .read = vicam_read, |
1237 | .mmap = vicam_mmap, | 1237 | .mmap = vicam_mmap, |
1238 | .ioctl = vicam_ioctl, | 1238 | .ioctl = vicam_ioctl, |
1239 | .compat_ioctl = v4l_compat_ioctl32, | ||
1239 | .llseek = no_llseek, | 1240 | .llseek = no_llseek, |
1240 | }; | 1241 | }; |
1241 | 1242 | ||
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 3605a6f3067b..bff9434c8e55 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c | |||
@@ -3490,6 +3490,7 @@ static struct file_operations w9968cf_fops = { | |||
3490 | .release = w9968cf_release, | 3490 | .release = w9968cf_release, |
3491 | .read = w9968cf_read, | 3491 | .read = w9968cf_read, |
3492 | .ioctl = w9968cf_ioctl, | 3492 | .ioctl = w9968cf_ioctl, |
3493 | .compat_ioctl = v4l_compat_ioctl32, | ||
3493 | .mmap = w9968cf_mmap, | 3494 | .mmap = w9968cf_mmap, |
3494 | .llseek = no_llseek, | 3495 | .llseek = no_llseek, |
3495 | }; | 3496 | }; |