Skip to contentSkip to conversation

saa7134 driver update

PATCH New Gerd Knorr 1 participant 1 message Oct 7, 2003 Media (V4L/DVB)

lore
Share & tools
lore

Gerd Knorr

author
#0 lore raw

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
diff -u linux-2.6.0-test6/drivers/media/video/saa7134/saa6752hs.c linux/drivers/media/video/saa7134/saa6752hs.c
@@ -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
diff -u linux-2.6.0-test6/drivers/media/video/saa7134/saa7134-i2c.c linux/drivers/media/video/saa7134/saa7134-i2c.c
@@ -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,
+#endif
 	I2C_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
diff -u linux-2.6.0-test6/drivers/media/video/saa7134/saa7134-oss.c linux/drivers/media/video/saa7134/saa7134-oss.c
@@ -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
diff -u linux-2.6.0-test6/drivers/media/video/saa7134/saa7134-reg.h linux/drivers/media/video/saa7134/saa7134-reg.h
@@ -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
diff -u linux-2.6.0-test6/drivers/media/video/saa7134/saa7134-vbi.c linux/drivers/media/video/saa7134/saa7134-vbi.c
@@ -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