saa7134 driver update
PATCH 1/1 saa7134 driver update
Hi,
This patch updates the saa7134 driver. It depends on the videobuf patch.
Changes:
* add support for mplex mpeg2 encoder cards (new saa6752hs module).
* tv card list updates.
* adapt to videobuf changes.
* better sysfs support.
Please apply,
Gerd
drivers/media/video/saa7134/saa6752hs.c +406 -0
@@ -0,0 +1,406 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/poll.h> +#include <linux/i2c.h> +#include <linux/types.h> +#include <linux/videodev.h> +#include <linux/init.h> + +#include <media/id.h> +#include <media/saa6752hs.h> + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {0x20 ,I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END }; +I2C_CLIENT_INSMOD ; + +MODULE_DESCRIPTION ("device driver for saa6752hs MPEG2 encoder" ); +MODULE_AUTHOR ("Andrew de Quincey" ); +MODULE_LICENSE ("GPL" ); + +static struct i2c_driver driver; +static struct i2c_client client_template; + + +enum saa6752hs_command { +SAA6752HS_COMMAND_RESET =0 , +SAA6752HS_COMMAND_STOP =1 , +SAA6752HS_COMMAND_START =2 , +SAA6752HS_COMMAND_PAUSE =3 , +SAA6752HS_COMMAND_RECONFIGURE =4 , +SAA6752HS_COMMAND_SLEEP =5 , +SAA6752HS_COMMAND_RECONFIGURE_FORCE =6 , + +SAA6752HS_COMMAND_MAX +}; + + +/* ---------------------------------------------------------------------- */ + +static u8 PAT [] = { +0xc2 ,// i2c register +0x00 ,// table number for encoder + +0x47 ,// sync +0x40 ,0x00 ,// transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) +0x10 ,// transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) + +0x00 ,// PSI pointer to start of table + +0x00 ,// tid(0) +0xb0 ,0x0d ,// section_syntax_indicator(1), section_length(13) + +0x00 ,0x01 ,// transport_stream_id(1) + +0xc1 ,// version_number(0), current_next_indicator(1) + +0x00 ,0x00 ,// section_number(0), last_section_number(0) + +0x00 ,0x01 ,// program_number(1) + +0xe0 ,0x10 ,// PMT PID(0x10) + +0x76 ,0xf1 ,0x44 ,0xd1 // CRC32 +}; + +static u8 PMT [] = { +0xc2 ,// i2c register +0x01 ,// table number for encoder + +0x47 ,// sync +0x40 ,0x10 ,// transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0x10) +0x10 ,// transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) + +0x00 ,// PSI pointer to start of table + +0x02 ,// tid(2) +0xb0 ,0x17 ,// section_syntax_indicator(1), section_length(23) + +0x00 ,0x01 ,// program_number(1) + +0xc1 ,// version_number(0), current_next_indicator(1) + +0x00 ,0x00 ,// section_number(0), last_section_number(0) + +0xe1 ,0x04 ,// PCR_PID (0x104) + +0xf0 ,0x00 ,// program_info_length(0) + +0x02 ,0xe1 ,0x00 ,0xf0 ,0x00 ,// video stream type(2), pid(0x100) +0x04 ,0xe1 ,0x03 ,0xf0 ,0x00 ,// audio stream type(4), pid(0x103) + +0xa1 ,0xca ,0x0f ,0x82 // CRC32 +}; + +static struct mpeg_params mpeg_params_template = +{ + .bitrate_mode =MPEG_BITRATE_MODE_CBR , + .video_target_bitrate =5000 , + .audio_bitrate =MPEG_AUDIO_BITRATE_256 , + .total_bitrate =6000 , +}; + + +/* ---------------------------------------------------------------------- */ + + +static int saa6752hs_chip_command (struct i2c_client * client, +enum saa6752hs_command command) +{ +unsigned char buf[3 ]; +unsigned long timeout; +int status =0 ; + +// execute the command +switch (command) { +case SAA6752HS_COMMAND_RESET : + buf[0 ] =0x00 ; +break ; + +case SAA6752HS_COMMAND_STOP : + buf[0 ] =0x03 ; +break ; + +case SAA6752HS_COMMAND_START : + buf[0 ] =0x02 ; +break ; + +case SAA6752HS_COMMAND_PAUSE : + buf[0 ] =0x04 ; +break ; + +case SAA6752HS_COMMAND_RECONFIGURE : + buf[0 ] =0x05 ; +break ; + +case SAA6752HS_COMMAND_SLEEP : + buf[0 ] =0x06 ; +break ; + +case SAA6752HS_COMMAND_RECONFIGURE_FORCE : + buf[0 ] =0x07 ; +break ; + +default : +return -EINVAL ; + } + +// set it and wait for it to be so +i2c_master_send (client, buf,1 ); + timeout = jiffies +HZ *3 ; +for (;;) { +// get the current status + buf[0 ] =0x10 ; +i2c_master_send (client, buf,1 ); +i2c_master_recv (client, buf,1 ); + +if (!(buf[0 ] &0x20 )) +break ; +if (time_after (jiffies,timeout)) { + status = -ETIMEDOUT ; +break ; + } + +// wait a bit + current->state =TASK_INTERRUPTIBLE ; +schedule_timeout (1 ); + } + +// delay a bit to let encoder settle + current->state =TASK_INTERRUPTIBLE ; +schedule_timeout (5 ); + +// done +return status; +} + + +static int saa6752hs_set_bitrate (struct i2c_client * client, +struct mpeg_params * params) +{ +u8 buf[3 ]; + +// set the bitrate mode + buf[0 ] =0x71 ; + buf[1 ] = params->bitrate_mode; +i2c_master_send (client, buf,2 ); + +// set the video bitrate +if (params->bitrate_mode ==MPEG_BITRATE_MODE_VBR ) { +// set the target bitrate + buf[0 ] =0x80 ; + buf[1 ] = params->video_target_bitrate >>8 ; + buf[2 ] = params->video_target_bitrate &0xff ; +i2c_master_send (client, buf,3 ); + +// set the max bitrate + buf[0 ] =0x81 ; + buf[1 ] = params->video_max_bitrate >>8 ; + buf[2 ] = params->video_max_bitrate &0xff ; +i2c_master_send (client, buf,3 ); + }else { +// set the target bitrate (no max bitrate for CBR) + buf[0 ] =0x81 ; + buf[1 ] = params->video_target_bitrate >>8 ; + buf[2 ] = params->video_target_bitrate &0xff ; +i2c_master_send (client, buf,3 ); + } + +// set the audio bitrate + buf[0 ] =0x94 ; + buf[1 ] = params->audio_bitrate; +i2c_master_send (client, buf,2 ); + +// set the total bitrate + buf[0 ] =0xb1 ; + buf[1 ] = params->total_bitrate >>8 ; + buf[2 ] = params->total_bitrate &0xff ; +i2c_master_send (client, buf,3 ); + +return 0 ; +} + + +static int saa6752hs_init (struct i2c_client * client,struct mpeg_params * params) +{ +unsigned char buf[3 ]; + +// check the bitrate parameters first +if (params !=NULL ) { +if (params->bitrate_mode >=MPEG_BITRATE_MODE_MAX ) +return -EINVAL ; +if (params->video_target_bitrate >=MPEG_VIDEO_TARGET_BITRATE_MAX ) +return -EINVAL ; +if (params->video_max_bitrate >=MPEG_VIDEO_MAX_BITRATE_MAX ) +return -EINVAL ; +if (params->audio_bitrate >=MPEG_AUDIO_BITRATE_MAX ) +return -EINVAL ; +if (params->total_bitrate >=MPEG_TOTAL_BITRATE_MAX ) +return -EINVAL ; +if (params->bitrate_mode ==MPEG_BITRATE_MODE_MAX && + params->video_target_bitrate <= params->video_max_bitrate) +return -EINVAL ; + } + +// Set GOP structure {3, 13} + buf[0 ] =0x72 ; + buf[1 ] =0x03 ; + buf[2 ] =0x0D ; +i2c_master_send (client,buf,3 ); + +// Set minimum Q-scale {4} + buf[0 ] =0x82 ; + buf[1 ] =0x04 ; +i2c_master_send (client,buf,2 ); + +// Set maximum Q-scale {12} + buf[0 ] =0x83 ; + buf[1 ] =0x0C ; +i2c_master_send (client,buf,2 ); + +// Set Output Protocol + buf[0 ] =0xD0 ; + buf[1 ] =0x01 ; +i2c_master_send (client,buf,2 ); + +// Set video output stream format {TS} + buf[0 ] =0xB0 ; + buf[1 ] =0x05 ; +i2c_master_send (client,buf,2 ); + +// Set Audio PID {0x103} + buf[0 ] =0xC1 ; + buf[1 ] =0x01 ; + buf[2 ] =0x03 ; +i2c_master_send (client,buf,3 ); + +// setup bitrate settings +if (params) { +saa6752hs_set_bitrate (client, params); +memcpy (client->data, params,sizeof (struct mpeg_params )); + }else { +// parameters were not supplied. use the previous set +saa6752hs_set_bitrate (client, (struct mpeg_params *) client->data); + } + +// Send SI tables +i2c_master_send (client,PAT ,sizeof (PAT )); +i2c_master_send (client,PMT ,sizeof (PMT )); + +// mute then unmute audio. This removes buzzing artefacts + buf[0 ] =0xa4 ; + buf[1 ] =1 ; +i2c_master_send (client, buf,2 ); + buf[1 ] =0 ; +i2c_master_send (client, buf,2 ); + +// start it going +saa6752hs_chip_command (client,SAA6752HS_COMMAND_START ); + +return 0 ; +} + +static int saa6752hs_attach (struct i2c_adapter *adap,int addr,int kind) +{ +struct i2c_client *client; +struct mpeg_params * params; + + client_template.adapter = adap; + client_template.addr = addr; + +printk ("saa6752hs: chip found @ 0x%x\n" , addr<<1 ); + +if (NULL == (client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL ))) +return -ENOMEM ; +memcpy (client,&client_template,sizeof (struct i2c_client )); +strlcpy (client->name,"saa6752hs" ,sizeof (client->name)); + +if (NULL == (params =kmalloc (sizeof (struct mpeg_params ),GFP_KERNEL ))) +return -ENOMEM ; +memcpy (params,&mpeg_params_template,sizeof (struct mpeg_params )); + client->data = params; + +i2c_attach_client (client); + +return 0 ; +} + +static int saa6752hs_probe (struct i2c_adapter *adap) +{ +if (adap->class &I2C_ADAP_CLASS_TV_ANALOG ) +return i2c_probe (adap, &addr_data, saa6752hs_attach); + +return 0 ; +} + +static int saa6752hs_detach (struct i2c_client *client) +{ +i2c_detach_client (client); +kfree (client->data); +kfree (client); +return 0 ; +} + +static int +saa6752hs_command (struct i2c_client *client,unsigned int cmd,void *arg) +{ +struct mpeg_params * init_arg = arg; + +switch (cmd) { +case MPEG_SETPARAMS : +return saa6752hs_init (client, init_arg); + +default : +/* nothing */ +break ; + } + +return 0 ; +} + +/* ----------------------------------------------------------------------- */ + +static struct i2c_driver driver = { + .owner =THIS_MODULE , + .name ="i2c saa6752hs MPEG encoder" , + .id =I2C_DRIVERID_SAA6752HS , + .flags =I2C_DF_NOTIFY , + .attach_adapter = saa6752hs_probe, + .detach_client = saa6752hs_detach, + .command = saa6752hs_command, +}; + +static struct i2c_client client_template = +{ +I2C_DEVNAME ("(saa6752hs unset)" ), + .flags =I2C_CLIENT_ALLOW_USE , + .driver = &driver, +}; + +static int saa6752hs_init_module (void ) +{ +i2c_add_driver (&driver); +return 0 ; +} + +static void saa6752hs_cleanup_module (void ) +{ +i2c_del_driver (&driver); +} + +module_init (saa6752hs_init_module); +module_exit (saa6752hs_cleanup_module); + +/* +* Overrides for Emacs so that we follow Linus's tabbing style. +* --------------------------------------------------------------------------- +* Local variables: +* c-basic-offset: 8 +* End: +*/
drivers/media/video/saa7134/saa7134-cards.c +176 -20
270 lines not on this page · raw message
drivers/media/video/saa7134/saa7134-core.c +195 -111
476 lines not on this page · raw message
drivers/media/video/saa7134/saa7134-i2c.c +20 -0
@@ -311,6 +311,17 @@return I2C_FUNC_SMBUS_EMUL ; } +#ifndef I2C_PEC +static void inc_use (struct i2c_adapter *adap) +{ +MOD_INC_USE_COUNT ; +} + +static void dec_use (struct i2c_adapter *adap) +{ +MOD_DEC_USE_COUNT ; +} +#endif static int attach_inform (struct i2c_client *client) {
@@ -330,8 +341,15 @@ };static struct i2c_adapter saa7134_adap_template = { +#ifdef I2C_PEC .owner =THIS_MODULE , +#else + .inc_use = inc_use, + .dec_use = dec_use, +#endif +#ifdef I2C_ADAP_CLASS_TV_ANALOG .class =I2C_ADAP_CLASS_TV_ANALOG , +#endifI2C_DEVNAME ("saa7134" ), .id =I2C_ALGO_SAA7134 , .algo = &saa7134_algo,
@@ -393,12 +411,14 @@void saa7134_i2c_call_clients (struct saa7134_dev *dev,unsigned int cmd,void *arg) { +BUG_ON (NULL == dev->i2c_adap.algo_data);i2c_clients_command (&dev->i2c_adap, cmd, arg); }int saa7134_i2c_register (struct saa7134_dev *dev) { dev->i2c_adap = saa7134_adap_template; + dev->i2c_adap.dev.parent = &dev->pci->dev;strcpy (dev->i2c_adap.name,dev->name); dev->i2c_adap.algo_data = dev;i2c_add_adapter (&dev->i2c_adap);
drivers/media/video/saa7134/saa7134-oss.c +1 -1
@@ -732,7 +732,7 @@/* ------------------------------------------------------------------ */ -int saa7134_oss_init (struct saa7134_dev *dev) +int saa7134_oss_init1 (struct saa7134_dev *dev) {/* general */ init_MUTEX (&dev->oss.lock);
drivers/media/video/saa7134/saa7134-reg.h +13 -0
@@ -101,7 +101,15 @@#define SAA7134_IRQ1_INTE_RA0_2 (1 << 2)#define SAA7134_IRQ1_INTE_RA0_1 (1 << 1)#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0) +#define SAA7134_IRQ2 (0x2c8 >> 2) +#define SAA7134_IRQ2_INTE_GPIO23A (1 << 17) +#define SAA7134_IRQ2_INTE_GPIO23 (1 << 16) +#define SAA7134_IRQ2_INTE_GPIO22A (1 << 15) +#define SAA7134_IRQ2_INTE_GPIO22 (1 << 14) +#define SAA7134_IRQ2_INTE_GPIO18A (1 << 13) +#define SAA7134_IRQ2_INTE_GPIO18 (1 << 12) +#define SAA7134_IRQ2_INTE_GPIO16 (1 << 11)/* not certain */ #define SAA7134_IRQ2_INTE_SC2 (1 << 10)#define SAA7134_IRQ2_INTE_SC1 (1 << 9)#define SAA7134_IRQ2_INTE_SC0 (1 << 8)
@@ -113,7 +121,12 @@#define SAA7134_IRQ2_INTE_DEC0 (1 << 2)#define SAA7134_IRQ2_INTE_PE (1 << 1)#define SAA7134_IRQ2_INTE_AR (1 << 0) +#define SAA7134_IRQ_REPORT (0x2cc >> 2) +#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17) +#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16) +#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15) +#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14)/* not certain */ #define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13)#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12)#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11)
drivers/media/video/saa7134/saa7134-ts.c +47 -3
117 lines not on this page · raw message
drivers/media/video/saa7134/saa7134-tvaudio.c +33 -17
101 lines not on this page · raw message
drivers/media/video/saa7134/saa7134-vbi.c +2 -2
@@ -146,7 +146,7 @@ buf->vb.size = size; buf->pt = &fh->pt_vbi; - err =videobuf_iolock (dev->pci,&buf->vb); + err =videobuf_iolock (dev->pci,&buf->vb,NULL );if (err) goto oops; err = saa7134_pgtable_build(dev->pci,buf->pt,
@@ -215,7 +215,7 @@/* ------------------------------------------------------------------ */ -int saa7134_vbi_init (struct saa7134_dev *dev) +int saa7134_vbi_init1 (struct saa7134_dev *dev) {INIT_LIST_HEAD (&dev->vbi_q.queue);init_timer (&dev->vbi_q.timeout);
drivers/media/video/saa7134/saa7134-video.c +130 -108
340 lines not on this page · raw message
drivers/media/video/saa7134/saa7134.h +52 -12
160 lines not on this page · raw message
include/media/saa6752hs.h +58 -0
58 lines not on this page · raw message
Signature · 1 line
You have a new virus in /var/mail/kraxel