diff options
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r-- | drivers/media/video/saa7134/saa6752hs.c | 105 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-alsa.c | 4 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-cards.c | 181 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-dvb.c | 10 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-empress.c | 86 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-i2c.c | 2 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 81 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-reg.h | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-tvaudio.c | 35 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-video.c | 82 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 6 |
12 files changed, 532 insertions, 62 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 002e70a33a4..707be175509 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -13,7 +13,6 @@ #include <linux/init.h> #include <linux/crc32.h> - #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 #define MPEG_VIDEO_MAX_BITRATE_MAX 27000 #define MPEG_TOTAL_TARGET_BITRATE_MAX 27000 @@ -21,6 +20,7 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; + I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); @@ -448,6 +448,104 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, return 0; } +static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, + struct v4l2_queryctrl *qctrl) +{ + int err; + + switch (qctrl->id) { + case V4L2_CID_MPEG_AUDIO_ENCODING: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2); + + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_L2_BITRATE_256K, + V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, + V4L2_MPEG_AUDIO_L2_BITRATE_256K); + + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); + + case V4L2_CID_MPEG_VIDEO_ENCODING: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2); + + case V4L2_CID_MPEG_VIDEO_ASPECT: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ASPECT_4x3, + V4L2_MPEG_VIDEO_ASPECT_16x9, 1, + V4L2_MPEG_VIDEO_ASPECT_4x3); + + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: + err = v4l2_ctrl_query_fill_std(qctrl); + if (err == 0 && + params->vi_bitrate_mode == + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) + qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; + return err; + + case V4L2_CID_MPEG_STREAM_TYPE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS); + + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + case V4L2_CID_MPEG_VIDEO_BITRATE: + case V4L2_CID_MPEG_STREAM_PID_PMT: + case V4L2_CID_MPEG_STREAM_PID_AUDIO: + case V4L2_CID_MPEG_STREAM_PID_VIDEO: + case V4L2_CID_MPEG_STREAM_PID_PCR: + return v4l2_ctrl_query_fill_std(qctrl); + + default: + break; + } + return -EINVAL; +} + +static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params, + struct v4l2_querymenu *qmenu) +{ + static const char *mpeg_audio_l2_bitrate[] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "256 kbps", + "", + "384 kbps", + NULL + }; + struct v4l2_queryctrl qctrl; + int err; + + qctrl.id = qmenu->id; + err = saa6752hs_qctrl(params, &qctrl); + if (err) + return err; + if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE) + return v4l2_ctrl_query_menu(qmenu, &qctrl, + mpeg_audio_l2_bitrate); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + v4l2_ctrl_get_menu(qmenu->id)); +} + static int saa6752hs_init(struct i2c_client* client) { unsigned char buf[9], buf2[4]; @@ -609,7 +707,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) i2c_attach_client(&h->client); v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); - return 0; } @@ -662,6 +759,10 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) } h->params = params; break; + case VIDIOC_QUERYCTRL: + return saa6752hs_qctrl(&h->params, arg); + case VIDIOC_QUERYMENU: + return saa6752hs_qmenu(&h->params, arg); case VIDIOC_G_FMT: { struct v4l2_format *f = arg; diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index f118de6e367..9929d20320b 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -80,7 +80,6 @@ typedef struct snd_card_saa7134 { } snd_card_saa7134_t; - /* * PCM structure */ @@ -1121,6 +1120,3 @@ late_initcall(saa7134_alsa_init); module_exit(saa7134_alsa_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ricardo Cerqueira"); - - - diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 2618cfa592e..6893f998d29 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -1287,6 +1287,22 @@ struct saa7134_board saa7134_boards[] = { .vmux = 8, }}, }, + [SAA7134_BOARD_AVERMEDIA_M103] = { + /* Massimo Piccioni <dafastidio@libero.it> */ + .name = "AVerMedia MiniPCI DVB-T Hybrid M103", + .audio_clock = 0x187de7, + .tuner_type = TUNER_XC2028, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + } }, + }, [SAA7134_BOARD_NOVAC_PRIMETV7133] = { /* toshii@netbsd.org */ .name = "Noval Prime TV 7133", @@ -3503,6 +3519,39 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .gpio = 0x0200000, }, + }, + [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = { + .name = "ASUSTeK P7131 Analog", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .gpiomask = 1 << 21, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x0000000, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE2, + }, { + .name = name_comp2, + .vmux = 0, + .amux = LINE2, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, }, [SAA7134_BOARD_SABRENT_TV_PCB05] = { .name = "Sabrent PCMCIA TV-PCB05", @@ -3940,32 +3989,111 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_BEHOLD_M6] = { /* Igor Kuznetsov <igk@igk.ru> */ /* Andrey Melnikoff <temnota@kmv.ru> */ - .name = "Beholder BeholdTV M6 / BeholdTV M6 Extra", + /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ + .name = "Beholder BeholdTV M6", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .inputs = {{ + .inputs = { { .name = name_tv, .vmux = 3, .amux = TV, .tv = 1, - },{ + }, { .name = name_comp1, .vmux = 1, .amux = LINE1, - },{ + }, { .name = name_svideo, .vmux = 8, .amux = LINE1, - }}, + } }, .radio = { .name = name_radio, .amux = LINE2, }, .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), + }, + [SAA7134_BOARD_BEHOLD_M63] = { + /* Igor Kuznetsov <igk@igk.ru> */ + /* Andrey Melnikoff <temnota@kmv.ru> */ + /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ + .name = "Beholder BeholdTV M63", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = { { + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), + }, + [SAA7134_BOARD_BEHOLD_M6_EXTRA] = { + /* Igor Kuznetsov <igk@igk.ru> */ + /* Andrey Melnikoff <temnota@kmv.ru> */ + /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ + .name = "Beholder BeholdTV M6 Extra", + .audio_clock = 0x00187de7, + /* FIXME: Must be PHILIPS_FM1216ME_MK5*/ + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = { { + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), }, [SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = { .name = "Twinhan Hybrid DTV-DVB 3056 PCI", @@ -4121,9 +4249,9 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .tv = 1, }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE2, + .name = name_comp, + .vmux = 0, + .amux = LINE1, }, { .name = name_svideo, .vmux = 8, @@ -4141,6 +4269,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 1, @@ -4150,6 +4279,10 @@ struct saa7134_board saa7134_boards[] = { .name = name_svideo, .vmux = 8, .amux = LINE1, + }, { + .name = name_comp, + .vmux = 0, + .amux = LINE1, } }, .radio = { .name = name_radio, @@ -4163,7 +4296,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 1, @@ -5226,13 +5358,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x5ace, .subdevice = 0x6193, - .driver_data = SAA7134_BOARD_BEHOLD_M6, + .driver_data = SAA7134_BOARD_BEHOLD_M6_EXTRA, }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x5ace, .subdevice = 0x6191, - .driver_data = SAA7134_BOARD_BEHOLD_M6, + .driver_data = SAA7134_BOARD_BEHOLD_M63, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -5284,10 +5416,22 @@ struct pci_device_id saa7134_pci_tbl[] = { }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5169, + .subdevice = 0x1502, + .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x5ace, .subdevice = 0x6290, .driver_data = SAA7134_BOARD_BEHOLD_H6, }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0xf636, + .driver_data = SAA7134_BOARD_AVERMEDIA_M103, + }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -5352,6 +5496,7 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev, saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); switch (dev->board) { case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); saa7134_set_gpio(dev, 23, 1); @@ -5493,6 +5638,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBT_LR301: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: + case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: case SAA7134_BOARD_FLYDVBTDUO: case SAA7134_BOARD_PROTEUS_2309: case SAA7134_BOARD_AVERMEDIA_A16AR: @@ -5560,6 +5706,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) msleep(10); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); saa7134_set_gpio(dev, 23, 1); @@ -5601,6 +5748,8 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_HAUPPAUGE_HVR1110: case SAA7134_BOARD_BEHOLD_607_9FM: case SAA7134_BOARD_BEHOLD_M6: + case SAA7134_BOARD_BEHOLD_M63: + case SAA7134_BOARD_BEHOLD_M6_EXTRA: dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: @@ -5683,6 +5832,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_AVERMEDIA_A16D: case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + case SAA7134_BOARD_AVERMEDIA_M103: ctl.demod = XC3028_FE_ZARLINK456; break; default: @@ -5825,6 +5975,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } + case SAA7134_BOARD_ASUSTeK_TVFM7135: + /* The card below is detected as card=53, but is different */ + if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { + dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; + printk(KERN_INFO "%s: P7131 analog only, using " + "entry of %s\n", + dev->name, saa7134_boards[dev->board].name); + } + break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: hauppauge_eeprom(dev, dev->eedata+0x80); /* break intentionally omitted */ diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 2c19cd0113c..cfee84ee7a8 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -150,7 +150,6 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value) #if defined(CONFIG_MODULES) && defined(MODULE) - static void request_module_async(struct work_struct *work){ struct saa7134_dev* dev = container_of(work, struct saa7134_dev, request_module_wk); if (card_is_empress(dev)) diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 341b101b035..be48b9b66a6 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1263,6 +1263,7 @@ static int dvb_init(struct saa7134_dev *dev) &avermedia_xc3028_mt352_dev, &dev->i2c_adap); attach_xc3028 = 1; + break; case SAA7134_BOARD_MD7134_BRIDGE_2: dev->dvb.frontend = dvb_attach(tda10086_attach, &sd1878_4m, &dev->i2c_adap); @@ -1290,6 +1291,15 @@ static int dvb_init(struct saa7134_dev *dev) fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage; } break; + case SAA7134_BOARD_AVERMEDIA_M103: + saa7134_set_gpio(dev, 25, 0); + msleep(10); + saa7134_set_gpio(dev, 25, 1); + dev->dvb.frontend = dvb_attach(mt352_attach, + &avermedia_xc3028_mt352_dev, + &dev->i2c_adap); + attach_xc3028 = 1; + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 3ae71a34082..2a5ab957542 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -208,7 +208,7 @@ static int empress_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int empress_enum_fmt_cap(struct file *file, void *priv, +static int empress_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index != 0) @@ -220,7 +220,7 @@ static int empress_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int empress_g_fmt_cap(struct file *file, void *priv, +static int empress_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = file->private_data; @@ -233,7 +233,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv, return 0; } -static int empress_s_fmt_cap(struct file *file, void *priv, +static int empress_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = file->private_data; @@ -294,10 +294,20 @@ static int empress_streamoff(struct file *file, void *priv, return videobuf_streamoff(&dev->empress_tsq); } +static int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; + return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, + cmd, arg); +} + static int empress_s_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { struct saa7134_dev *dev = file->private_data; + int err; /* count == 0 is abused in saa6752hs.c, so that special case is handled here explicitly. */ @@ -307,10 +317,10 @@ static int empress_s_ext_ctrls(struct file *file, void *priv, if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, ctrls); + err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls); ts_init_encoder(dev); - return 0; + return err; } static int empress_g_ext_ctrls(struct file *file, void *priv, @@ -320,9 +330,62 @@ static int empress_g_ext_ctrls(struct file *file, void *priv, if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, ctrls); + return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls); +} - return 0; +static int empress_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *c) +{ + static const u32 user_ctrls[] = { + V4L2_CID_USER_CLASS, + V4L2_CID_BRIGHTNESS, + V4L2_CID_CONTRAST, + V4L2_CID_SATURATION, + V4L2_CID_HUE, + V4L2_CID_AUDIO_VOLUME, + V4L2_CID_AUDIO_MUTE, + V4L2_CID_HFLIP, + 0 + }; + + static const u32 mpeg_ctrls[] = { + V4L2_CID_MPEG_CLASS, + V4L2_CID_MPEG_STREAM_TYPE, + V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, + V4L2_CID_MPEG_AUDIO_ENCODING, + V4L2_CID_MPEG_AUDIO_L2_BITRATE, + V4L2_CID_MPEG_VIDEO_ENCODING, + V4L2_CID_MPEG_VIDEO_ASPECT, + V4L2_CID_MPEG_VIDEO_BITRATE_MODE, + V4L2_CID_MPEG_VIDEO_BITRATE, + V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, + 0 + }; + static const u32 *ctrl_classes[] = { + user_ctrls, + mpeg_ctrls, + NULL + }; + struct saa7134_dev *dev = file->private_data; + + c->id = v4l2_ctrl_next(ctrl_classes, c->id); + if (c->id == 0) + return -EINVAL; + if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS) + return v4l2_ctrl_query_fill_std(c); + if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) + return saa7134_queryctrl(file, priv, c); + return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c); +} + +static int empress_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *c) +{ + struct saa7134_dev *dev = file->private_data; + + if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c); } static const struct file_operations ts_fops = @@ -348,9 +411,9 @@ static struct video_device saa7134_empress_template = .minor = -1, .vidioc_querycap = empress_querycap, - .vidioc_enum_fmt_cap = empress_enum_fmt_cap, - .vidioc_s_fmt_cap = empress_s_fmt_cap, - .vidioc_g_fmt_cap = empress_g_fmt_cap, + .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, .vidioc_reqbufs = empress_reqbufs, .vidioc_querybuf = empress_querybuf, .vidioc_qbuf = empress_qbuf, @@ -363,7 +426,8 @@ static struct video_device saa7134_empress_template = .vidioc_g_input = empress_g_input, .vidioc_s_input = empress_s_input, - .vidioc_queryctrl = saa7134_queryctrl, + .vidioc_queryctrl = empress_queryctrl, + .vidioc_querymenu = empress_querymenu, .vidioc_g_ctrl = saa7134_g_ctrl, .vidioc_s_ctrl = saa7134_s_ctrl, diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index d8af3863f2d..5f713e63768 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -327,6 +327,8 @@ static int attach_inform(struct i2c_client *client) d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", client->driver->driver.name, client->addr, client->name); + if (client->addr == 0x20 && client->driver && client->driver->command) + dev->mpeg_i2c_client = client; /* Am I an i2c remote control? */ diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 76e6501d238..ad08d13dffd 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -198,6 +198,84 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } +/* Common (grey or coloured) pinnacle PCTV remote handling + * + */ +static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, + int parity_offset, int marker, int code_modulo) +{ + unsigned char b[4]; + unsigned int start = 0,parity = 0,code = 0; + + /* poll IR chip */ + if (4 != i2c_master_recv(&ir->c, b, 4)) { + i2cdprintk("read error\n"); + return -EIO; + } + + for (start = 0; start < ARRAY_SIZE(b); start++) { + if (b[start] == marker) { + code=b[(start+parity_offset + 1) % 4]; + parity=b[(start+parity_offset) % 4]; + } + } + + /* Empty Request */ + if (parity == 0) + return 0; + + /* Repeating... */ + if (ir->old == parity) + return 0; + + ir->old = parity; + + /* drop special codes when a key is held down a long time for the grey controller + In this case, the second bit of the code is asserted */ + if (marker == 0xfe && (code & 0x40)) + return 0; + + code %= code_modulo; + + *ir_raw = code; + *ir_key = code; + + i2cdprintk("Pinnacle PCTV key %02x\n", code); + + return 1; +} + +/* The grey pinnacle PCTV remote + * + * There are one issue with this remote: + * - I2c packet does not change when the same key is pressed quickly. The workaround + * is to hold down each key for about half a second, so that another code is generated + * in the i2c packet, and the function can distinguish key presses. + * + * Sylvain Pasche <sylvain.pasche@gmail.com> + */ +static int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + + return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); +} + + +/* The new pinnacle PCTV remote (with the colored buttons) + * + * Ricardo Cerqueira <v4l@cerqueira.org> + */ +static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE + * + * this is the only value that results in 42 unique + * codes < 128 + */ + + return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); +} + void saa7134_input_irq(struct saa7134_dev *dev) { struct card_ir *ir = dev->remote; @@ -409,6 +487,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: + case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: ir_codes = ir_codes_asus_pc39; mask_keydown = 0x0040000; rc5_gpio = 1; @@ -540,6 +619,8 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) break; case SAA7134_BOARD_BEHOLD_607_9FM: case SAA7134_BOARD_BEHOLD_M6: + case SAA7134_BOARD_BEHOLD_M63: + case SAA7134_BOARD_BEHOLD_M6_EXTRA: case SAA7134_BOARD_BEHOLD_H6: snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); ir->get_key = get_key_beholdm6xx; diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h index 86f5eefdb0f..cf89d96d729 100644 --- a/drivers/media/video/saa7134/saa7134-reg.h +++ b/drivers/media/video/saa7134/saa7134-reg.h @@ -368,6 +368,7 @@ #define SAA7135_DSP_RWCLEAR 0x586 #define SAA7135_DSP_RWCLEAR_RERR 1 +#define SAA7133_I2S_AUDIO_CONTROL 0x591 /* ------------------------------------------------------------------ */ /* * Local variables: diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 232af598d94..c5d0b44c179 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -477,7 +477,6 @@ static int tvaudio_thread(void *data) unsigned int i, audio, nscan; int max1,max2,carrier,rx,mode,lastmode,default_carrier; - set_freezable(); for (;;) { @@ -775,7 +774,6 @@ static int tvaudio_thread_ddep(void *data) struct saa7134_dev *dev = data; u32 value, norms; - set_freezable(); for (;;) { tvaudio_sleep(dev,-1); @@ -873,13 +871,34 @@ void saa7134_enable_i2s(struct saa7134_dev *dev) if (!card_is_empress(dev)) return; - i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01; - /* enable I2S audio output for the mpeg encoder */ - saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80); - saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format); - saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F); - saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01); + if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130) + return; + + /* configure GPIO for out */ + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000); + + switch (dev->pci->device) { + case PCI_DEVICE_ID_PHILIPS_SAA7133: + case PCI_DEVICE_ID_PHILIPS_SAA7135: + /* Set I2S format (SONY) */ + saa_writeb(SAA7133_I2S_AUDIO_CONTROL, 0x00); + /* Start I2S */ + saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11); + break; + + case PCI_DEVICE_ID_PHILIPS_SAA7134: + i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01; + + /* enable I2S audio output for the mpeg encoder */ + saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80); + saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format); + saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F); + saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01); + + default: + break; + } } int saa7134_tvaudio_rx2mode(u32 rx) diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 48e1a01718e..1a5137550e7 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1496,7 +1496,7 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma) /* ------------------------------------------------------------------ */ -static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv, +static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1516,7 +1516,7 @@ static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv, return 0; } -static int saa7134_g_fmt_cap(struct file *file, void *priv, +static int saa7134_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1532,7 +1532,7 @@ static int saa7134_g_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_g_fmt_overlay(struct file *file, void *priv, +static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1546,7 +1546,7 @@ static int saa7134_g_fmt_overlay(struct file *file, void *priv, return 0; } -static int saa7134_try_fmt_cap(struct file *file, void *priv, +static int saa7134_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1597,7 +1597,7 @@ static int saa7134_try_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_try_fmt_overlay(struct file *file, void *priv, +static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1611,13 +1611,13 @@ static int saa7134_try_fmt_overlay(struct file *file, void *priv, return verify_preview(dev, &f->fmt.win); } -static int saa7134_s_fmt_cap(struct file *file, void *priv, +static int saa7134_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; int err; - err = saa7134_try_fmt_cap(file, priv, f); + err = saa7134_try_fmt_vid_cap(file, priv, f); if (0 != err) return err; @@ -1628,7 +1628,7 @@ static int saa7134_s_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_s_fmt_overlay(struct file *file, void *priv, +static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -2028,7 +2028,7 @@ static int saa7134_s_priority(struct file *file, void *f, return v4l2_prio_change(&dev->prio, &fh->prio, prio); } -static int saa7134_enum_fmt_cap(struct file *file, void *priv, +static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index >= FORMATS) @@ -2042,7 +2042,7 @@ static int saa7134_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_enum_fmt_overlay(struct file *file, void *priv, +static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (saa7134_no_overlay > 0) { @@ -2061,7 +2061,7 @@ static int saa7134_enum_fmt_overlay(struct file *file, void *priv, return 0; } -static int saa7134_enum_fmt_vbi(struct file *file, void *priv, +static int saa7134_enum_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (0 != f->index) @@ -2208,6 +2208,32 @@ static int saa7134_g_parm(struct file *file, void *fh, return 0; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int vidioc_g_register (struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return -EINVAL; + reg->val = saa_readb(reg->reg); + return 0; +} + +static int vidioc_s_register (struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return -EINVAL; + saa_writeb(reg->reg&0xffffff, reg->val); + return 0; +} +#endif + static int radio_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -2348,18 +2374,18 @@ struct video_device saa7134_video_template = .fops = &video_fops, .minor = -1, .vidioc_querycap = saa7134_querycap, - .vidioc_enum_fmt_cap = saa7134_enum_fmt_cap, - .vidioc_g_fmt_cap = saa7134_g_fmt_cap, - .vidioc_try_fmt_cap = saa7134_try_fmt_cap, - .vidioc_s_fmt_cap = saa7134_s_fmt_cap, - .vidioc_enum_fmt_overlay = saa7134_enum_fmt_overlay, - .vidioc_g_fmt_overlay = saa7134_g_fmt_overlay, - .vidioc_try_fmt_overlay = saa7134_try_fmt_overlay, - .vidioc_s_fmt_overlay = saa7134_s_fmt_overlay, - .vidioc_enum_fmt_vbi = saa7134_enum_fmt_vbi, - .vidioc_g_fmt_vbi = saa7134_try_get_set_fmt_vbi, - .vidioc_try_fmt_vbi = saa7134_try_get_set_fmt_vbi, - .vidioc_s_fmt_vbi = saa7134_try_get_set_fmt_vbi, + .vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = saa7134_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = saa7134_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_overlay = saa7134_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_overlay = saa7134_g_fmt_vid_overlay, + .vidioc_try_fmt_vid_overlay = saa7134_try_fmt_vid_overlay, + .vidioc_s_fmt_vid_overlay = saa7134_s_fmt_vid_overlay, + .vidioc_enum_fmt_vbi_cap = saa7134_enum_fmt_vbi_cap, + .vidioc_g_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, + .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, + .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, .vidioc_g_audio = saa7134_g_audio, .vidioc_s_audio = saa7134_s_audio, .vidioc_cropcap = saa7134_cropcap, @@ -2391,6 +2417,10 @@ struct video_device saa7134_video_template = .vidioc_g_parm = saa7134_g_parm, .vidioc_g_frequency = saa7134_g_frequency, .vidioc_s_frequency = saa7134_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif .tvnorms = SAA7134_NORMS, .current_norm = V4L2_STD_PAL, }; @@ -2458,13 +2488,14 @@ int saa7134_videoport_init(struct saa7134_dev *dev) int vo = saa7134_boards[dev->board].video_out; int video_reg; unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts; + + /* Configure videoport */ saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); video_reg = video_out[vo][1]; if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED) video_reg &= ~VP_T_CODE_P_INVERTED; saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg); saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); - saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); video_reg = video_out[vo][5]; if (vid_port_opts & SET_CLOCK_NOT_DELAYED) @@ -2481,6 +2512,9 @@ int saa7134_videoport_init(struct saa7134_dev *dev) saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); + /* Start videoport */ + saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); + return 0; } diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 34ff0d4998f..6927cbea862 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -264,7 +264,10 @@ struct saa7134_format { #define SAA7134_BOARD_AVERMEDIA_A700_PRO 140 #define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141 #define SAA7134_BOARD_BEHOLD_H6 142 - +#define SAA7134_BOARD_BEHOLD_M63 143 +#define SAA7134_BOARD_BEHOLD_M6_EXTRA 144 +#define SAA7134_BOARD_AVERMEDIA_M103 145 +#define SAA7134_BOARD_ASUSTeK_P7131_ANALOG 146 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 @@ -552,6 +555,7 @@ struct saa7134_dev { struct saa7134_ts ts; struct saa7134_dmaqueue ts_q; struct saa7134_mpeg_ops *mops; + struct i2c_client *mpeg_i2c_client; /* SAA7134_MPEG_EMPRESS only */ struct video_device *empress_dev; |