summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c68
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.h1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.c3
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.h4
-rw-r--r--linux/drivers/media/radio/Kconfig2
-rw-r--r--linux/drivers/media/radio/radio-si470x.c234
-rw-r--r--linux/drivers/media/video/adv7170.c257
-rw-r--r--linux/drivers/media/video/adv7175.c247
-rw-r--r--linux/drivers/media/video/bt819.c325
-rw-r--r--linux/drivers/media/video/bt856.c222
-rw-r--r--linux/drivers/media/video/bt866.c261
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-core.c11
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-dvb.c164
-rw-r--r--linux/drivers/media/video/cx23885/cx23885.h5
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c37
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c399
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c17
-rw-r--r--linux/drivers/media/video/cx88/cx88-mpeg.c22
-rw-r--r--linux/drivers/media/video/cx88/cx88.h6
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_bridge.h29
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_core.c46
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c18
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_mt9m111.h3
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_ov9650.c40
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_ov9650.h3
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_po1030.c90
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_po1030.h46
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c22
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h3
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c6
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h4
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_sensor.h2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-fileops.c15
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c18
-rw-r--r--linux/drivers/media/video/ks0127.c478
-rw-r--r--linux/drivers/media/video/saa7110.c248
-rw-r--r--linux/drivers/media/video/saa7111.c228
-rw-r--r--linux/drivers/media/video/saa7114.c368
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c216
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h2
-rw-r--r--linux/drivers/media/video/saa7185.c214
-rw-r--r--linux/drivers/media/video/stk-webcam.c27
-rw-r--r--linux/drivers/media/video/stk-webcam.h1
-rw-r--r--linux/drivers/media/video/videobuf-dvb.c175
-rw-r--r--linux/drivers/media/video/vpx3220.c334
-rw-r--r--linux/drivers/media/video/zoran/zoran_card.c1
46 files changed, 2082 insertions, 2840 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 43b31ec2c..51fb82edc 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -52,6 +52,7 @@ static int dvb_shutdown_timeout;
static int dvb_force_auto_inversion;
static int dvb_override_tune_delay;
static int dvb_powerdown_on_sleep = 1;
+static int dvb_mfe_wait_time = 5;
module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
@@ -63,6 +64,8 @@ module_param(dvb_override_tune_delay, int, 0644);
MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
module_param(dvb_powerdown_on_sleep, int, 0644);
MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
+module_param(dvb_mfe_wait_time, int, 0644);
+MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
#define dprintk if (dvb_frontend_debug) printk
@@ -217,8 +220,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
static void dvb_frontend_init(struct dvb_frontend *fe)
{
- dprintk ("DVB: initialising frontend %i (%s)...\n",
+ dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
fe->dvb->num,
+ fe->id,
fe->ops.info.name);
if (fe->ops.init)
@@ -697,7 +701,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
mb();
fe_thread = kthread_run(dvb_frontend_thread, fe,
- "kdvb-fe-%i", fe->dvb->num);
+ "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
if (IS_ERR(fe_thread)) {
ret = PTR_ERR(fe_thread);
printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
@@ -721,8 +725,8 @@ static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
*freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
if (*freq_min == 0 || *freq_max == 0)
- printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n",
- fe->dvb->num);
+ printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
+ fe->dvb->num,fe->id);
}
static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
@@ -735,8 +739,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
if ((freq_min && parms->frequency < freq_min) ||
(freq_max && parms->frequency > freq_max)) {
- printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n",
- fe->dvb->num, parms->frequency, freq_min, freq_max);
+ printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max);
return -EINVAL;
}
@@ -746,8 +750,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
- printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
- fe->dvb->num, parms->u.qpsk.symbol_rate,
+ printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL;
}
@@ -757,8 +761,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
- printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
- fe->dvb->num, parms->u.qam.symbol_rate,
+ printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, parms->u.qam.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL;
}
@@ -1133,6 +1137,7 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe)
switch(c->modulation) {
case PSK_8:
case APSK_16:
+ case APSK_32:
case QPSK:
p->u.qpsk.symbol_rate = c->symbol_rate;
p->u.qpsk.fec_inner = c->fec_inner;
@@ -1819,13 +1824,46 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ struct dvb_adapter *adapter = fe->dvb;
+ struct dvb_device *mfedev;
+ struct dvb_frontend *mfe;
+ struct dvb_frontend_private *mfepriv;
+ int mferetry;
int ret;
dprintk ("%s\n", __func__);
+ if (adapter->mfe_shared) {
+ mutex_lock (&adapter->mfe_lock);
+ if (adapter->mfe_dvbdev != dvbdev) {
+ if (adapter->mfe_dvbdev) {
+ mfedev = adapter->mfe_dvbdev;
+ mfe = mfedev->priv;
+ mfepriv = mfe->frontend_priv;
+ mutex_unlock (&adapter->mfe_lock);
+ mferetry = (dvb_mfe_wait_time << 1);
+ while (mferetry-- && (mfedev->users != -1 || mfepriv->thread != NULL)) {
+ if(msleep_interruptible(500)) {
+ if(signal_pending(current))
+ return -EINTR;
+ }
+ }
+ mutex_lock (&adapter->mfe_lock);
+ mfedev = adapter->mfe_dvbdev;
+ mfe = mfedev->priv;
+ mfepriv = mfe->frontend_priv;
+ if (mfedev->users != -1 || mfepriv->thread != NULL) {
+ ret = -EBUSY;
+ goto err0;
+ }
+ }
+ adapter->mfe_dvbdev = dvbdev;
+ }
+ }
+
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
- return ret;
+ goto err0;
}
if ((ret = dvb_generic_open (inode, file)) < 0)
@@ -1845,6 +1883,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
fepriv->events.eventr = fepriv->events.eventw = 0;
}
+ if (adapter->mfe_shared)
+ mutex_unlock (&adapter->mfe_lock);
return ret;
err2:
@@ -1852,6 +1892,9 @@ err2:
err1:
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
+err0:
+ if (adapter->mfe_shared)
+ mutex_unlock (&adapter->mfe_lock);
return ret;
}
@@ -1921,8 +1964,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF;
- printk ("DVB: registering frontend %i (%s)...\n",
+ printk ("DVB: registering adapter %i frontend %i (%s)...\n",
fe->dvb->num,
+ fe->id,
fe->ops.info.name);
dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
index a0c591b3b..569b72a96 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -236,6 +236,7 @@ struct dvb_frontend {
struct dtv_frontend_properties dtv_property_cache;
#define DVB_FRONTEND_COMPONENT_TUNER 0
int (*callback)(void *adapter_priv, int component, int cmd, int arg);
+ int id;
};
extern int dvb_register_frontend(struct dvb_adapter *dvb,
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c
index 0820da504..422af5a0d 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c
@@ -341,6 +341,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
adap->name = name;
adap->module = module;
adap->device = device;
+ adap->mfe_shared = 0;
+ adap->mfe_dvbdev = NULL;
+ mutex_init (&adap->mfe_lock);
list_add_tail (&adap->list_head, &dvb_adapter_list);
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h
index 89d12dc47..574e336ba 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h
@@ -62,6 +62,10 @@ struct dvb_adapter {
struct device *device;
struct module *module;
+
+ int mfe_shared; /* indicates mutually exclusive frontends */
+ struct dvb_device *mfe_dvbdev; /* frontend device in use */
+ struct mutex mfe_lock; /* access lock for thread creation */
};
diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig
index e51d707e5..04cd7c04b 100644
--- a/linux/drivers/media/radio/Kconfig
+++ b/linux/drivers/media/radio/Kconfig
@@ -359,7 +359,7 @@ config USB_SI470X
computer's USB port.
To compile this driver as a module, choose M here: the
- module will be called radio-silabs.
+ module will be called radio-si470x.
config USB_MR800
tristate "AverMedia MR 800 USB FM radio support"
diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c
index 871a63a87..e332b3de5 100644
--- a/linux/drivers/media/radio/radio-si470x.c
+++ b/linux/drivers/media/radio/radio-si470x.c
@@ -104,6 +104,7 @@
* - hardware frequency seek support
* - afc indication
* - more safety checks, let si470x_get_freq return errno
+ * - vidioc behavior corrected according to v4l2 spec
*
* ToDo:
* - add firmware download/update support
@@ -142,9 +143,9 @@
/* USB Device ID List */
static struct usb_device_id si470x_usb_driver_id_table[] = {
/* Silicon Labs USB FM Radio Reference Design */
- { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
- { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
/* Terminating entry */
{ }
};
@@ -158,7 +159,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
/* Radio Nr */
static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* Spacing (kHz) */
@@ -166,42 +167,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* 1: 100 kHz (Europe, Japan) */
/* 2: 50 kHz */
static unsigned short space = 2;
-module_param(space, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
+module_param(space, ushort, 0444);
+MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
/* Bottom of Band (MHz) */
/* 0: 87.5 - 108 MHz (USA, Europe)*/
/* 1: 76 - 108 MHz (Japan wide band) */
/* 2: 76 - 90 MHz (Japan) */
static unsigned short band = 1;
-module_param(band, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
+module_param(band, ushort, 0444);
+MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
/* De-emphasis */
/* 0: 75 us (USA) */
/* 1: 50 us (Europe, Australia, Japan) */
static unsigned short de = 1;
-module_param(de, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
+module_param(de, ushort, 0444);
+MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
/* USB timeout */
static unsigned int usb_timeout = 500;
-module_param(usb_timeout, uint, 0);
+module_param(usb_timeout, uint, 0644);
MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
/* Tune timeout */
static unsigned int tune_timeout = 3000;
-module_param(tune_timeout, uint, 0);
+module_param(tune_timeout, uint, 0644);
MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
/* Seek timeout */
static unsigned int seek_timeout = 5000;
-module_param(seek_timeout, uint, 0);
+module_param(seek_timeout, uint, 0644);
MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
/* RDS buffer blocks */
static unsigned int rds_buf = 100;
-module_param(rds_buf, uint, 0);
+module_param(rds_buf, uint, 0444);
MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
/* RDS maximum block errors */
@@ -210,7 +211,7 @@ static unsigned short max_rds_errors = 1;
/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
/* 2 means 3-5 errors requiring correction */
/* 3 means 6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, ushort, 0);
+module_param(max_rds_errors, ushort, 0644);
MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
/* RDS poll frequency */
@@ -219,7 +220,7 @@ static unsigned int rds_poll_time = 40;
/* 50 is used by radio-cadet */
/* 75 should be okay */
/* 80 is the usual RDS receive interval */
-module_param(rds_poll_time, uint, 0);
+module_param(rds_poll_time, uint, 0644);
MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
@@ -672,23 +673,29 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
int retval;
/* Spacing (kHz) */
- switch (space) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
/* 0: 200 kHz (USA, Australia) */
- case 0 : spacing = 0.200 * FREQ_MUL; break;
+ case 0:
+ spacing = 0.200 * FREQ_MUL; break;
/* 1: 100 kHz (Europe, Japan) */
- case 1 : spacing = 0.100 * FREQ_MUL; break;
+ case 1:
+ spacing = 0.100 * FREQ_MUL; break;
/* 2: 50 kHz */
- default: spacing = 0.050 * FREQ_MUL; break;
+ default:
+ spacing = 0.050 * FREQ_MUL; break;
};
/* Bottom of Band (MHz) */
- switch (band) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe) */
- case 0 : band_bottom = 87.5 * FREQ_MUL; break;
+ case 0:
+ band_bottom = 87.5 * FREQ_MUL; break;
/* 1: 76 - 108 MHz (Japan wide band) */
- default: band_bottom = 76 * FREQ_MUL; break;
+ default:
+ band_bottom = 76 * FREQ_MUL; break;
/* 2: 76 - 90 MHz (Japan) */
- case 2 : band_bottom = 76 * FREQ_MUL; break;
+ case 2:
+ band_bottom = 76 * FREQ_MUL; break;
};
/* read channel */
@@ -711,23 +718,29 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
unsigned short chan;
/* Spacing (kHz) */
- switch (space) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
/* 0: 200 kHz (USA, Australia) */
- case 0 : spacing = 0.200 * FREQ_MUL; break;
+ case 0:
+ spacing = 0.200 * FREQ_MUL; break;
/* 1: 100 kHz (Europe, Japan) */
- case 1 : spacing = 0.100 * FREQ_MUL; break;
+ case 1:
+ spacing = 0.100 * FREQ_MUL; break;
/* 2: 50 kHz */
- default: spacing = 0.050 * FREQ_MUL; break;
+ default:
+ spacing = 0.050 * FREQ_MUL; break;
};
/* Bottom of Band (MHz) */
- switch (band) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe) */
- case 0 : band_bottom = 87.5 * FREQ_MUL; break;
+ case 0:
+ band_bottom = 87.5 * FREQ_MUL; break;
/* 1: 76 - 108 MHz (Japan wide band) */
- default: band_bottom = 76 * FREQ_MUL; break;
+ default:
+ band_bottom = 76 * FREQ_MUL; break;
/* 2: 76 - 90 MHz (Japan) */
- case 2 : band_bottom = 76 * FREQ_MUL; break;
+ case 2:
+ band_bottom = 76 * FREQ_MUL; break;
};
/* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
@@ -1169,7 +1182,6 @@ static const struct file_operations si470x_fops = {
* si470x_v4l2_queryctrl - query control
*/
static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
-/* HINT: the disabled controls are only here to satify kradio and such apps */
{
.id = V4L2_CID_AUDIO_VOLUME,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -1180,18 +1192,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
.default_value = 15,
},
{
- .id = V4L2_CID_AUDIO_BALANCE,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_AUDIO_BASS,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_AUDIO_TREBLE,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
.id = V4L2_CID_AUDIO_MUTE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Mute",
@@ -1200,10 +1200,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
.step = 1,
.default_value = 1,
},
- {
- .id = V4L2_CID_AUDIO_LOUDNESS,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
};
@@ -1225,56 +1221,34 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
/*
- * si470x_vidioc_g_input - get input
- */
-static int si470x_vidioc_g_input(struct file *file, void *priv,
- unsigned int *i)
-{
- *i = 0;
-
- return 0;
-}
-
-
-/*
- * si470x_vidioc_s_input - set input
- */
-static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- int retval = 0;
-
- /* safety checks */
- if (i != 0)
- retval = -EINVAL;
-
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME
- ": set input failed with %d\n", retval);
- return retval;
-}
-
-
-/*
* si470x_vidioc_queryctrl - enumerate control items
*/
static int si470x_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- unsigned char i;
+ unsigned char i = 0;
int retval = -EINVAL;
- /* safety checks */
- if (!qc->id)
+ /* abort if qc->id is below V4L2_CID_BASE */
+ if (qc->id < V4L2_CID_BASE)
goto done;
+ /* search video control */
for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
if (qc->id == si470x_v4l2_queryctrl[i].id) {
memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
- retval = 0;
+ retval = 0; /* found */
break;
}
}
+ /* disable unsupported base controls */
+ /* to satisfy kradio and such apps */
+ if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
+ qc->flags = V4L2_CTRL_FLAG_DISABLED;
+ retval = 0;
+ }
+
done:
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
@@ -1365,44 +1339,13 @@ done:
static int si470x_vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- int retval = 0;
-
- /* safety checks */
- if (audio->index != 0) {
- retval = -EINVAL;
- goto done;
- }
-
+ /* driver constants */
+ audio->index = 0;
strcpy(audio->name, "Radio");
audio->capability = V4L2_AUDCAP_STEREO;
+ audio->mode = 0;
-done:
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME
- ": get audio failed with %d\n", retval);
- return retval;
-}
-
-
-/*
- * si470x_vidioc_s_audio - set audio attributes
- */
-static int si470x_vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *audio)
-{
- int retval = 0;
-
- /* safety checks */
- if (audio->index != 0) {
- retval = -EINVAL;
- goto done;
- }
-
-done:
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME
- ": set audio failed with %d\n", retval);
- return retval;
+ return 0;
}
@@ -1420,7 +1363,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
+ if (tuner->index != 0) {
retval = -EINVAL;
goto done;
}
@@ -1429,8 +1372,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
if (retval < 0)
goto done;
+ /* driver constants */
strcpy(tuner->name, "FM");
- switch (band) {
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+
+ /* range limits */
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe, default) */
default:
tuner->rangelow = 87.5 * FREQ_MUL;
@@ -1447,14 +1395,18 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
tuner->rangehigh = 90 * FREQ_MUL;
break;
};
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- tuner->capability = V4L2_TUNER_CAP_LOW;
- /* Stereo indicator == Stereo (instead of Mono) */
+ /* stereo indicator == stereo (instead of mono) */
if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1)
- tuner->audmode = V4L2_TUNER_MODE_STEREO;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
else
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+
+ /* mono/stereo selector */
+ if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1)
tuner->audmode = V4L2_TUNER_MODE_MONO;
+ else
+ tuner->audmode = V4L2_TUNER_MODE_STEREO;
/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI)
@@ -1479,22 +1431,27 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
struct si470x_device *radio = video_drvdata(file);
- int retval = 0;
+ int retval = -EINVAL;
/* safety checks */
if (radio->disconnected) {
retval = -EIO;
goto done;
}
- if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
- retval = -EINVAL;
+ if (tuner->index != 0)
goto done;
- }
- if (tuner->audmode == V4L2_TUNER_MODE_MONO)
+ /* mono/stereo selector */
+ switch (tuner->audmode) {
+ case V4L2_TUNER_MODE_MONO:
radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
- else
+ break;
+ case V4L2_TUNER_MODE_STEREO:
radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
+ break;
+ default:
+ goto done;
+ }
retval = si470x_set_register(radio, POWERCFG);
@@ -1520,11 +1477,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+ if (freq->tuner != 0) {
retval = -EINVAL;
goto done;
}
+ freq->type = V4L2_TUNER_RADIO;
retval = si470x_get_freq(radio, &freq->frequency);
done:
@@ -1549,7 +1507,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+ if (freq->tuner != 0) {
retval = -EINVAL;
goto done;
}
@@ -1578,7 +1536,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) {
+ if (seek->tuner != 0) {
retval = -EINVAL;
goto done;
}
@@ -1593,15 +1551,16 @@ done:
return retval;
}
+
+/*
+ * si470x_ioctl_ops - video device ioctl operations
+ */
static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_querycap = si470x_vidioc_querycap,
- .vidioc_g_input = si470x_vidioc_g_input,
- .vidioc_s_input = si470x_vidioc_s_input,
.vidioc_queryctrl = si470x_vidioc_queryctrl,
.vidioc_g_ctrl = si470x_vidioc_g_ctrl,
.vidioc_s_ctrl = si470x_vidioc_s_ctrl,
.vidioc_g_audio = si470x_vidioc_g_audio,
- .vidioc_s_audio = si470x_vidioc_s_audio,
.vidioc_g_tuner = si470x_vidioc_g_tuner,
.vidioc_s_tuner = si470x_vidioc_s_tuner,
.vidioc_g_frequency = si470x_vidioc_g_frequency,
@@ -1609,14 +1568,15 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
};
+
/*
- * si470x_viddev_tamples - video device interface
+ * si470x_viddev_template - video device interface
*/
static struct video_device si470x_viddev_template = {
.fops = &si470x_fops,
- .ioctl_ops = &si470x_ioctl_ops,
.name = DRIVER_NAME,
.release = video_device_release,
+ .ioctl_ops = &si470x_ioctl_ops,
};
diff --git a/linux/drivers/media/video/adv7170.c b/linux/drivers/media/video/adv7170.c
index 54ef7aa63..0a319ad8e 100644
--- a/linux/drivers/media/video/adv7170.c
+++ b/linux/drivers/media/video/adv7170.c
@@ -29,44 +29,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
-#include "compat.h"
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include "compat.h"
MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(x) (x)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct adv7170 {
@@ -81,21 +62,12 @@ struct adv7170 {
int sat;
};
-#define I2C_ADV7170 0xd4
-#define I2C_ADV7171 0x54
-
-static char adv7170_name[] = "adv7170";
-static char adv7171_name[] = "adv7171";
-
static char *inputs[] = { "pass_through", "play_back" };
static char *norms[] = { "PAL", "NTSC" };
/* ----------------------------------------------------------------------- */
-static inline int
-adv7170_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
{
struct adv7170 *encoder = i2c_get_clientdata(client);
@@ -103,17 +75,13 @@ adv7170_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-adv7170_read (struct i2c_client *client,
- u8 reg)
+static inline int adv7170_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-adv7170_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int adv7170_write_block(struct i2c_client *client,
+ const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -134,33 +102,25 @@ adv7170_write_block (struct i2c_client *client,
encoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = adv7170_write(client, reg,
- *data++)) < 0)
+ ret = adv7170_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
}
-
return ret;
}
/* ----------------------------------------------------------------------- */
-// Output filter: S-Video Composite
-
-#define MR050 0x11 //0x09
-#define MR060 0x14 //0x0c
-
-//---------------------------------------------------------------------------
#define TR0MODE 0x4c
#define TR0RST 0x80
@@ -168,7 +128,6 @@ adv7170_write_block (struct i2c_client *client,
#define TR1CAPT 0x00
#define TR1PLAY 0x00
-
static const unsigned char init_NTSC[] = {
0x00, 0x10, // MR0
0x01, 0x20, // MR1
@@ -228,15 +187,11 @@ static const unsigned char init_PAL[] = {
};
-static int
-adv7170_command (struct i2c_client *client,
- unsigned int cmd,
- void * arg)
+static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct adv7170 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
#if 0 /* keep */
/* This is just for testing!!! */
@@ -255,18 +210,16 @@ adv7170_command (struct i2c_client *client,
VIDEO_ENCODER_NTSC;
cap->inputs = 2;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
int iarg = *(int *) arg;
- dprintk(1, KERN_DEBUG "%s_command: set norm %d",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "set norm %d\n", iarg);
switch (iarg) {
-
case VIDEO_MODE_NTSC:
adv7170_write_block(client, init_NTSC,
sizeof(init_NTSC));
@@ -286,16 +239,13 @@ adv7170_command (struct i2c_client *client,
break;
default:
- dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
- norms[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
encoder->norm = iarg;
- }
break;
+ }
case ENCODER_SET_INPUT:
{
@@ -305,19 +255,17 @@ adv7170_command (struct i2c_client *client,
*iarg = 1: input is from ZR36060
*iarg = 2: color bar */
- dprintk(1, KERN_DEBUG "%s_command: set input from %s\n",
- I2C_NAME(client),
+ v4l_dbg(1, debug, client, "set input from %s\n",
iarg == 0 ? "decoder" : "ZR36060");
switch (iarg) {
-
case 0:
adv7170_write(client, 0x01, 0x20);
adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
adv7170_write(client, 0x02, 0x0e); // Enable genlock
adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
case 1:
@@ -326,20 +274,17 @@ adv7170_command (struct i2c_client *client,
adv7170_write(client, 0x02, 0x08);
adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
default:
- dprintk(1, KERN_ERR "%s: illegal input: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
- inputs[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
encoder->input = iarg;
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
@@ -349,16 +294,16 @@ adv7170_command (struct i2c_client *client,
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
- }
break;
+ }
default:
return -EINVAL;
@@ -369,149 +314,71 @@ adv7170_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
- { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1,
- I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
+static unsigned short normal_i2c[] = {
+ 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */
+ 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */
I2C_CLIENT_END
};
-static unsigned short ignore = I2C_CLIENT_END;
+I2C_CLIENT_INSMOD;
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver i2c_driver_adv7170;
-
-static int
-adv7170_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int adv7170_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int i;
- struct i2c_client *client;
struct adv7170 *encoder;
- char *dname;
-
- dprintk(1,
- KERN_INFO
- "adv7170.c: detecting adv7170 client on address 0x%x\n",
- address << 1);
+ int i;
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_adv7170;
- if ((client->addr == I2C_ADV7170 >> 1) ||
- (client->addr == (I2C_ADV7170 >> 1) + 1)) {
- dname = adv7170_name;
- } else if ((client->addr == I2C_ADV7171 >> 1) ||
- (client->addr == (I2C_ADV7171 >> 1) + 1)) {
- dname = adv7171_name;
- } else {
- /* We should never get here!!! */
- kfree(client);
- return 0;
- }
- strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_NTSC;
encoder->input = 0;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
if (i >= 0) {
i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
i = adv7170_write(client, 0x07, TR0MODE);
i = adv7170_read(client, 0x12);
- dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n",
- I2C_NAME(client), i & 1, client->addr << 1);
- }
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
- I2C_NAME(client), i);
+ v4l_dbg(1, debug, client, "revision %d\n", i & 1);
}
-
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init error 0x%x\n", i);
return 0;
}
-static int
-adv7170_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "adv7170.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &adv7170_detect_client);
-}
-
-static int
-adv7170_detach_client (struct i2c_client *client)
+static int adv7170_remove(struct i2c_client *client)
{
- struct adv7170 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(encoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_adv7170 = {
- .driver = {
- .name = "adv7170", /* name */
- },
-
- .id = I2C_DRIVERID_ADV7170,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id adv7170_id[] = {
+ { "adv7170", 0 },
+ { "adv7171", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7170_id);
- .attach_adapter = adv7170_attach_adapter,
- .detach_client = adv7170_detach_client,
+#endif
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "adv7170",
+ .driverid = I2C_DRIVERID_ADV7170,
.command = adv7170_command,
+ .probe = adv7170_probe,
+ .remove = adv7170_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = adv7170_id,
+#endif
};
-
-static int __init
-adv7170_init (void)
-{
- return i2c_add_driver(&i2c_driver_adv7170);
-}
-
-static void __exit
-adv7170_exit (void)
-{
- i2c_del_driver(&i2c_driver_adv7170);
-}
-
-module_init(adv7170_init);
-module_exit(adv7170_exit);
diff --git a/linux/drivers/media/video/adv7175.c b/linux/drivers/media/video/adv7175.c
index b8618c021..281a3f53c 100644
--- a/linux/drivers/media/video/adv7175.c
+++ b/linux/drivers/media/video/adv7175.c
@@ -25,44 +25,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
#include "compat.h"
MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct adv7175 {
@@ -78,33 +59,23 @@ struct adv7175 {
#define I2C_ADV7175 0xd4
#define I2C_ADV7176 0x54
-static char adv7175_name[] = "adv7175";
-static char adv7176_name[] = "adv7176";
-
static char *inputs[] = { "pass_through", "play_back", "color_bar" };
static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
/* ----------------------------------------------------------------------- */
-static inline int
-adv7175_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-adv7175_read (struct i2c_client *client,
- u8 reg)
+static inline int adv7175_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-adv7175_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int adv7175_write_block(struct i2c_client *client,
+ const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -124,18 +95,17 @@ adv7175_write_block (struct i2c_client *client,
reg++;
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = adv7175_write(client, reg,
- *data++)) < 0)
+ ret = adv7175_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -144,13 +114,11 @@ adv7175_write_block (struct i2c_client *client,
return ret;
}
-static void
-set_subcarrier_freq (struct i2c_client *client,
- int pass_through)
+static void set_subcarrier_freq(struct i2c_client *client, int pass_through)
{
/* for some reason pass_through NTSC needs
* a different sub-carrier freq to remain stable. */
- if(pass_through)
+ if (pass_through)
adv7175_write(client, 0x02, 0x00);
else
adv7175_write(client, 0x02, 0x55);
@@ -161,12 +129,12 @@ set_subcarrier_freq (struct i2c_client *client,
}
/* ----------------------------------------------------------------------- */
-// Output filter: S-Video Composite
+/* Output filter: S-Video Composite */
-#define MR050 0x11 //0x09
-#define MR060 0x14 //0x0c
+#define MR050 0x11 /* 0x09 */
+#define MR060 0x14 /* 0x0c */
-//---------------------------------------------------------------------------
+/* ----------------------------------------------------------------------- */
#define TR0MODE 0x46
#define TR0RST 0x80
@@ -217,15 +185,11 @@ static const unsigned char init_ntsc[] = {
0x06, 0x1a, /* subc. phase */
};
-static int
-adv7175_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct adv7175 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
/* This is just for testing!!! */
adv7175_write_block(client, init_common,
@@ -243,15 +207,14 @@ adv7175_command (struct i2c_client *client,
VIDEO_ENCODER_SECAM; /* well, hacky */
cap->inputs = 2;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
int iarg = *(int *) arg;
switch (iarg) {
-
case VIDEO_MODE_NTSC:
adv7175_write_block(client, init_ntsc,
sizeof(init_ntsc));
@@ -285,16 +248,13 @@ adv7175_command (struct i2c_client *client,
adv7175_write(client, 0x07, TR0MODE);
break;
default:
- dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
- norms[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
encoder->norm = iarg;
- }
break;
+ }
case ENCODER_SET_INPUT:
{
@@ -305,7 +265,6 @@ adv7175_command (struct i2c_client *client,
*iarg = 2: color bar */
switch (iarg) {
-
case 0:
adv7175_write(client, 0x01, 0x00);
@@ -332,7 +291,7 @@ adv7175_command (struct i2c_client *client,
adv7175_write(client, 0x0d, 0x49);
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
case 2:
@@ -344,39 +303,35 @@ adv7175_command (struct i2c_client *client,
adv7175_write(client, 0x0d, 0x49);
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
default:
- dprintk(1, KERN_ERR "%s: illegal input: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
- inputs[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
encoder->input = iarg;
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
- }
break;
+ }
default:
return -EINVAL;
@@ -391,145 +346,71 @@ adv7175_command (struct i2c_client *client,
* Generic i2c probe
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static unsigned short normal_i2c[] =
- { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
+static unsigned short normal_i2c[] = {
+ I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
I2C_CLIENT_END
};
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver i2c_driver_adv7175;
+I2C_CLIENT_INSMOD;
-static int
-adv7175_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int adv7175_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
- struct i2c_client *client;
struct adv7175 *encoder;
- char *dname;
-
- dprintk(1,
- KERN_INFO
- "adv7175.c: detecting adv7175 client on address 0x%x\n",
- address << 1);
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_adv7175;
- if ((client->addr == I2C_ADV7175 >> 1) ||
- (client->addr == (I2C_ADV7175 >> 1) + 1)) {
- dname = adv7175_name;
- } else if ((client->addr == I2C_ADV7176 >> 1) ||
- (client->addr == (I2C_ADV7176 >> 1) + 1)) {
- dname = adv7176_name;
- } else {
- /* We should never get here!!! */
- kfree(client);
- return 0;
- }
- strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_PAL;
encoder->input = 0;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
i = adv7175_write_block(client, init_common, sizeof(init_common));
if (i >= 0) {
i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
i = adv7175_write(client, 0x07, TR0MODE);
i = adv7175_read(client, 0x12);
- dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
- I2C_NAME(client), i & 1, client->addr << 1);
+ v4l_dbg(1, debug, client, "revision %d\n", i & 1);
}
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
- I2C_NAME(client), i);
- }
-
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init error 0x%x\n", i);
return 0;
}
-static int
-adv7175_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "adv7175.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
-}
-
-static int
-adv7175_detach_client (struct i2c_client *client)
+static int adv7175_remove(struct i2c_client *client)
{
- struct adv7175 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(encoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_adv7175 = {
- .driver = {
- .name = "adv7175", /* name */
- },
-
- .id = I2C_DRIVERID_ADV7175,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id adv7175_id[] = {
+ { "adv7175", 0 },
+ { "adv7176", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7175_id);
+#endif
- .attach_adapter = adv7175_attach_adapter,
- .detach_client = adv7175_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "adv7175",
+ .driverid = I2C_DRIVERID_ADV7175,
.command = adv7175_command,
+ .probe = adv7175_probe,
+ .remove = adv7175_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = adv7175_id,
+#endif
};
-
-static int __init
-adv7175_init (void)
-{
- return i2c_add_driver(&i2c_driver_adv7175);
-}
-
-static void __exit
-adv7175_exit (void)
-{
- i2c_del_driver(&i2c_driver_adv7175);
-}
-
-module_init(adv7175_init);
-module_exit(adv7175_exit);
diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c
index 90be239cc..201dd9277 100644
--- a/linux/drivers/media/video/bt819.c
+++ b/linux/drivers/media/video/bt819.c
@@ -29,45 +29,26 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
-
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
#include "compat.h"
MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct bt819 {
@@ -98,14 +79,9 @@ static struct timing timing_data[] = {
{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
};
-#define I2C_BT819 0x8a
-
/* ----------------------------------------------------------------------- */
-static inline int
-bt819_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
{
struct bt819 *decoder = i2c_get_clientdata(client);
@@ -113,24 +89,15 @@ bt819_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-bt819_setbit (struct i2c_client *client,
- u8 reg,
- u8 bit,
- u8 value)
+static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
{
struct bt819 *decoder = i2c_get_clientdata(client);
return bt819_write(client, reg,
- (decoder->
- reg[reg] & ~(1 << bit)) |
- (value ? (1 << bit) : 0));
+ (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
}
-static int
-bt819_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -151,10 +118,9 @@ bt819_write_block (struct i2c_client *client,
decoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
@@ -170,20 +136,17 @@ bt819_write_block (struct i2c_client *client,
return ret;
}
-static inline int
-bt819_read (struct i2c_client *client,
- u8 reg)
+static inline int bt819_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-bt819_init (struct i2c_client *client)
+static int bt819_init(struct i2c_client *client)
{
struct bt819 *decoder = i2c_get_clientdata(client);
static unsigned char init[] = {
- //0x1f, 0x00, /* Reset */
+ /*0x1f, 0x00,*/ /* Reset */
0x01, 0x59, /* 0x01 input format */
0x02, 0x00, /* 0x02 temporal decimation */
0x03, 0x12, /* 0x03 Cropping msb */
@@ -219,12 +182,10 @@ bt819_init (struct i2c_client *client)
struct timing *timing = &timing_data[decoder->norm];
init[0x03 * 2 - 1] =
- (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
- vactive >> 8) &
- 0x03) << 4) |
- (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
- hactive >> 8) &
- 0x03);
+ (((timing->vdelay >> 8) & 0x03) << 6) |
+ (((timing->vactive >> 8) & 0x03) << 4) |
+ (((timing->hdelay >> 8) & 0x03) << 2) |
+ ((timing->hactive >> 8) & 0x03);
init[0x04 * 2 - 1] = timing->vdelay & 0xff;
init[0x05 * 2 - 1] = timing->vactive & 0xff;
init[0x06 * 2 - 1] = timing->hdelay & 0xff;
@@ -239,27 +200,22 @@ bt819_init (struct i2c_client *client)
/* init */
return bt819_write_block(client, init, sizeof(init));
-
}
/* ----------------------------------------------------------------------- */
-static int
-bt819_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
{
int temp;
struct bt819 *decoder = i2c_get_clientdata(client);
- if (!decoder->initialized) { // First call to bt819_init could be
- bt819_init(client); // without #FRST = 0
+ if (!decoder->initialized) { /* First call to bt819_init could be */
+ bt819_init(client); /* without #FRST = 0 */
decoder->initialized = 1;
}
switch (cmd) {
-
case 0:
/* This is just for testing!!! */
bt819_init(client);
@@ -275,8 +231,8 @@ bt819_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -286,9 +242,9 @@ bt819_command (struct i2c_client *client,
status = bt819_read(client, 0x00);
res = 0;
- if ((status & 0x80)) {
+ if ((status & 0x80))
res |= DECODER_STATUS_GOOD;
- }
+
switch (decoder->norm) {
case VIDEO_MODE_NTSC:
res |= DECODER_STATUS_NTSC;
@@ -298,28 +254,25 @@ bt819_command (struct i2c_client *client,
break;
default:
case VIDEO_MODE_AUTO:
- if ((status & 0x10)) {
+ if ((status & 0x10))
res |= DECODER_STATUS_PAL;
- } else {
+ else
res |= DECODER_STATUS_NTSC;
- }
break;
}
res |= DECODER_STATUS_COLOR;
*iarg = res;
- dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
- *iarg);
- }
+ v4l_dbg(1, debug, client, "get status %x\n", *iarg);
break;
+ }
case DECODER_SET_NORM:
{
int *iarg = arg;
struct timing *timing = NULL;
- dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
switch (*iarg) {
case VIDEO_MODE_NTSC:
@@ -328,7 +281,7 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x01, 5, 0);
bt819_write(client, 0x18, 0x68);
bt819_write(client, 0x19, 0x5d);
- //bt819_setbit(client, 0x1a, 5, 1);
+ /* bt819_setbit(client, 0x1a, 5, 1); */
timing = &timing_data[VIDEO_MODE_NTSC];
break;
case VIDEO_MODE_PAL:
@@ -337,7 +290,7 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x01, 5, 1);
bt819_write(client, 0x18, 0x7f);
bt819_write(client, 0x19, 0x72);
- //bt819_setbit(client, 0x1a, 5, 0);
+ /* bt819_setbit(client, 0x1a, 5, 0); */
timing = &timing_data[VIDEO_MODE_PAL];
break;
case VIDEO_MODE_AUTO:
@@ -345,10 +298,7 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x01, 1, 0);
break;
default:
- dprintk(1,
- KERN_ERR
- "%s: unsupported norm %d\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
return -EINVAL;
}
@@ -367,19 +317,17 @@ bt819_command (struct i2c_client *client,
}
decoder->norm = *iarg;
- }
break;
+ }
case DECODER_SET_INPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set input %x\n", *iarg);
- if (*iarg < 0 || *iarg > 7) {
+ if (*iarg < 0 || *iarg > 7)
return -EINVAL;
- }
if (decoder->input != *iarg) {
decoder->input = *iarg;
@@ -392,52 +340,42 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x1a, 1, 0);
}
}
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set output %x\n", *iarg);
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
int enable = (*iarg != 0);
- dprintk(1, KERN_INFO "%s: enable output %x\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
if (decoder->enable != enable) {
decoder->enable = enable;
-
- if (decoder->enable) {
- bt819_setbit(client, 0x16, 7, 0);
- } else {
- bt819_setbit(client, 0x16, 7, 1);
- }
+ bt819_setbit(client, 0x16, 7, !enable);
}
- }
break;
+ }
case DECODER_SET_PICTURE:
{
struct video_picture *pic = arg;
- dprintk(1,
- KERN_INFO
- "%s: set picture brightness %d contrast %d colour %d\n",
- I2C_NAME(client), pic->brightness, pic->contrast,
- pic->colour);
+ v4l_dbg(1, debug, client,
+ "set picture brightness %d contrast %d colour %d\n",
+ pic->brightness, pic->contrast, pic->colour);
if (decoder->bright != pic->brightness) {
@@ -475,8 +413,8 @@ bt819_command (struct i2c_client *client,
bt819_write(client, 0x0f,
128 - (decoder->hue >> 8));
}
- }
break;
+ }
default:
return -EINVAL;
@@ -487,55 +425,44 @@ bt819_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = {
- I2C_BT819 >> 1,
- I2C_CLIENT_END,
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_bt819;
+I2C_CLIENT_INSMOD;
-static int
-bt819_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int bt819_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int i, id;
+ int i, ver;
struct bt819 *decoder;
- struct i2c_client *client;
-
- dprintk(1,
- KERN_INFO
- "bt819: detecting bt819 client on address 0x%x\n",
- address << 1);
+ const char *name;
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_bt819;
+ ver = bt819_read(client, 0x17);
+ switch (ver & 0xf0) {
+ case 0x70:
+ name = "bt819a";
+ break;
+ case 0x60:
+ name = "bt817a";
+ break;
+ case 0x20:
+ name = "bt815a";
+ break;
+ default:
+ v4l_dbg(1, debug, client,
+ "unknown chip version 0x%02x\n", ver);
+ return -ENODEV;
+ }
+
+ v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
+ if (decoder == NULL)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = 0;
decoder->enable = 1;
@@ -546,97 +473,37 @@ bt819_detect_client (struct i2c_adapter *adapter,
decoder->initialized = 0;
i2c_set_clientdata(client, decoder);
- id = bt819_read(client, 0x17);
- switch (id & 0xf0) {
- case 0x70:
- strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
- break;
- case 0x60:
- strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
- break;
- case 0x20:
- strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
- break;
- default:
- dprintk(1,
- KERN_ERR
- "bt819: unknown chip version 0x%x (ver 0x%x)\n",
- id & 0xf0, id & 0x0f);
- kfree(decoder);
- kfree(client);
- return 0;
- }
-
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
i = bt819_init(client);
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init status %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version 0x%x at address 0x%x\n",
- I2C_NAME(client), id & 0x0f,
- client->addr << 1);
- }
-
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init status %d\n", i);
return 0;
}
-static int
-bt819_attach_adapter (struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, &bt819_detect_client);
-}
-
-static int
-bt819_detach_client (struct i2c_client *client)
+static int bt819_remove(struct i2c_client *client)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_bt819 = {
- .driver = {
- .name = "bt819",
- },
-
- .id = I2C_DRIVERID_BT819,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id bt819_id[] = {
+ { "bt819a", 0 },
+ { "bt817a", 0 },
+ { "bt815a", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bt819_id);
- .attach_adapter = bt819_attach_adapter,
- .detach_client = bt819_detach_client,
+#endif
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "bt819",
+ .driverid = I2C_DRIVERID_BT819,
.command = bt819_command,
+ .probe = bt819_probe,
+ .remove = bt819_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = bt819_id,
+#endif
};
-
-static int __init
-bt819_init_module (void)
-{
- return i2c_add_driver(&i2c_driver_bt819);
-}
-
-static void __exit
-bt819_exit (void)
-{
- i2c_del_driver(&i2c_driver_bt819);
-}
-
-module_init(bt819_init_module);
-module_exit(bt819_exit);
diff --git a/linux/drivers/media/video/bt856.c b/linux/drivers/media/video/bt856.c
index e31c9d4b9..89c4061c7 100644
--- a/linux/drivers/media/video/bt856.c
+++ b/linux/drivers/media/video/bt856.c
@@ -29,44 +29,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
#include <linux/video_encoder.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
#include "compat.h"
-#include <linux/videodev.h>
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
#define BT856_REG_OFFSET 0xDA
@@ -79,14 +60,9 @@ struct bt856 {
int enable;
};
-#define I2C_BT856 0x88
-
/* ----------------------------------------------------------------------- */
-static inline int
-bt856_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
{
struct bt856 *encoder = i2c_get_clientdata(client);
@@ -94,46 +70,36 @@ bt856_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-bt856_setbit (struct i2c_client *client,
- u8 reg,
- u8 bit,
- u8 value)
+static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
{
struct bt856 *encoder = i2c_get_clientdata(client);
return bt856_write(client, reg,
- (encoder->
- reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
- (value ? (1 << bit) : 0));
+ (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
+ (value ? (1 << bit) : 0));
}
-static void
-bt856_dump (struct i2c_client *client)
+static void bt856_dump(struct i2c_client *client)
{
int i;
struct bt856 *encoder = i2c_get_clientdata(client);
- printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
+ v4l_info(client, "register dump:\n");
for (i = 0; i < BT856_NR_REG; i += 2)
- printk(" %02x", encoder->reg[i]);
- printk("\n");
+ printk(KERN_CONT " %02x", encoder->reg[i]);
+ printk(KERN_CONT "\n");
}
/* ----------------------------------------------------------------------- */
-static int
-bt856_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct bt856 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
/* This is just for testing!!! */
- dprintk(1, KERN_INFO "bt856: init\n");
+ v4l_dbg(1, debug, client, "init\n");
bt856_write(client, 0xdc, 0x18);
bt856_write(client, 0xda, 0);
bt856_write(client, 0xde, 0);
@@ -143,7 +109,6 @@ bt856_command (struct i2c_client *client,
bt856_setbit(client, 0xdc, 4, 1);
switch (encoder->norm) {
-
case VIDEO_MODE_NTSC:
bt856_setbit(client, 0xdc, 2, 0);
break;
@@ -164,26 +129,23 @@ bt856_command (struct i2c_client *client,
{
struct video_encoder_capability *cap = arg;
- dprintk(1, KERN_INFO "%s: get capabilities\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "get capabilities\n");
cap->flags = VIDEO_ENCODER_PAL |
VIDEO_ENCODER_NTSC |
VIDEO_ENCODER_CCIR;
cap->inputs = 2;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
bt856_setbit(client, 0xdc, 2, 0);
break;
@@ -196,27 +158,23 @@ bt856_command (struct i2c_client *client,
default:
return -EINVAL;
-
}
encoder->norm = *iarg;
if (debug != 0)
bt856_dump(client);
- }
break;
+ }
case ENCODER_SET_INPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set input %d\n", *iarg);
/* We only have video bus.
* iarg = 0: input is from bt819
* iarg = 1: input is from ZR36060 */
-
switch (*iarg) {
-
case 0:
bt856_setbit(client, 0xde, 4, 0);
bt856_setbit(client, 0xde, 3, 1);
@@ -235,27 +193,24 @@ bt856_command (struct i2c_client *client,
break;
default:
return -EINVAL;
-
}
if (debug != 0)
bt856_dump(client);
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set output %d\n", *iarg);
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
@@ -263,10 +218,9 @@ bt856_command (struct i2c_client *client,
encoder->enable = !!*iarg;
- dprintk(1, KERN_INFO "%s: enable output %d\n",
- I2C_NAME(client), encoder->enable);
- }
+ v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
break;
+ }
default:
return -EINVAL;
@@ -277,64 +231,29 @@ bt856_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_bt856;
+I2C_CLIENT_INSMOD;
-static int
-bt856_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int bt856_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int i;
- struct i2c_client *client;
struct bt856 *encoder;
- dprintk(1,
- KERN_INFO
- "bt856.c: detecting bt856 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_bt856;
- strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
bt856_write(client, 0xdc, 0x18);
bt856_write(client, 0xda, 0);
bt856_write(client, 0xde, 0);
@@ -360,65 +279,30 @@ bt856_detect_client (struct i2c_adapter *adapter,
if (debug != 0)
bt856_dump(client);
-
- dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
- client->addr << 1);
-
return 0;
}
-static int
-bt856_attach_adapter (struct i2c_adapter *adapter)
+static int bt856_remove(struct i2c_client *client)
{
- dprintk(1,
- KERN_INFO
- "bt856.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &bt856_detect_client);
-}
-
-static int
-bt856_detach_client (struct i2c_client *client)
-{
- struct bt856 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(encoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver i2c_driver_bt856 = {
- .driver = {
- .name = "bt856",
- },
-
- .id = I2C_DRIVERID_BT856,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id bt856_id[] = {
+ { "bt856", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bt856_id);
+#endif
- .attach_adapter = bt856_attach_adapter,
- .detach_client = bt856_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "bt856",
+ .driverid = I2C_DRIVERID_BT856,
.command = bt856_command,
+ .probe = bt856_probe,
+ .remove = bt856_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = bt856_id,
+#endif
};
-
-static int __init
-bt856_init (void)
-{
- return i2c_add_driver(&i2c_driver_bt856);
-}
-
-static void __exit
-bt856_exit (void)
-{
- i2c_del_driver(&i2c_driver_bt856);
-}
-
-module_init(bt856_init);
-module_exit(bt856_exit);
diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c
index 89161e867..aaa985c8e 100644
--- a/linux/drivers/media/video/bt866.c
+++ b/linux/drivers/media/video/bt866.c
@@ -29,43 +29,29 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
#include <linux/i2c.h>
-
-#include "compat.h"
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
-#include <asm/uaccess.h>
-
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include "compat.h"
+MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
+MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
-#define BT866_DEVNAME "bt866"
-#define I2C_BT866 0x88
-
-MODULE_LICENSE("GPL");
-
-#define DEBUG(x) /* Debug driver */
+static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct bt866 {
- struct i2c_client *i2c;
- int addr;
- unsigned char reg[256];
+ u8 reg[256];
int norm;
int enable;
@@ -75,20 +61,45 @@ struct bt866 {
int sat;
};
-static int bt866_write(struct bt866 *dev,
- unsigned char subaddr, unsigned char data);
+static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
+{
+ struct bt866 *encoder = i2c_get_clientdata(client);
+ u8 buffer[2];
+ int err;
+
+ buffer[0] = subaddr;
+ buffer[1] = data;
+
+ encoder->reg[subaddr] = data;
+
+ v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
-static int bt866_do_command(struct bt866 *encoder,
- unsigned int cmd, void *arg)
+ for (err = 0; err < 3;) {
+ if (i2c_master_send(client, buffer, 2) == 2)
+ break;
+ err++;
+ v4l_warn(client, "error #%d writing to 0x%02x\n",
+ err, subaddr);
+ schedule_timeout_interruptible(msecs_to_jiffies(100));
+ }
+ if (err == 3) {
+ v4l_warn(client, "giving up\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
{
+ struct bt866 *encoder = i2c_get_clientdata(client);
+
switch (cmd) {
case ENCODER_GET_CAPABILITIES:
{
struct video_encoder_capability *cap = arg;
- DEBUG(printk
- (KERN_INFO "%s: get capabilities\n",
- encoder->i2c->name));
+ v4l_dbg(1, debug, client, "get capabilities\n");
cap->flags
= VIDEO_ENCODER_PAL
@@ -96,18 +107,16 @@ static int bt866_do_command(struct bt866 *encoder,
| VIDEO_ENCODER_CCIR;
cap->inputs = 2;
cap->outputs = 1;
+ break;
}
- break;
case ENCODER_SET_NORM:
{
int *iarg = arg;
- DEBUG(printk(KERN_INFO "%s: set norm %d\n",
- encoder->i2c->name, *iarg));
+ v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
break;
@@ -116,11 +125,10 @@ static int bt866_do_command(struct bt866 *encoder,
default:
return -EINVAL;
-
}
encoder->norm = *iarg;
+ break;
}
- break;
case ENCODER_SET_INPUT:
{
@@ -156,7 +164,7 @@ static int bt866_do_command(struct bt866 *encoder,
u8 val;
for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
- bt866_write(encoder, init[i], init[i+1]);
+ bt866_write(client, init[i], init[i+1]);
val = encoder->reg[0xdc];
@@ -165,17 +173,16 @@ static int bt866_do_command(struct bt866 *encoder,
else
val &= ~0x40; /* !CBSWAP */
- bt866_write(encoder, 0xdc, val);
+ bt866_write(client, 0xdc, val);
val = encoder->reg[0xcc];
if (*iarg == 2)
val |= 0x01; /* OSDBAR */
else
val &= ~0x01; /* !OSDBAR */
- bt866_write(encoder, 0xcc, val);
+ bt866_write(client, 0xcc, val);
- DEBUG(printk(KERN_INFO "%s: set input %d\n",
- encoder->i2c->name, *iarg));
+ v4l_dbg(1, debug, client, "set input %d\n", *iarg);
switch (*iarg) {
case 0:
@@ -184,48 +191,44 @@ static int bt866_do_command(struct bt866 *encoder,
break;
default:
return -EINVAL;
-
}
+ break;
}
- break;
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
- DEBUG(printk(KERN_INFO "%s: set output %d\n",
- encoder->i2c->name, *iarg));
+ v4l_dbg(1, debug, client, "set output %d\n", *iarg);
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
+ break;
}
- break;
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
- DEBUG(printk
- (KERN_INFO "%s: enable output %d\n",
- encoder->i2c->name, encoder->enable));
+ v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+ break;
}
- break;
case 4711:
{
int *iarg = arg;
__u8 val;
- printk("bt866: square = %d\n", *iarg);
+ v4l_dbg(1, debug, client, "square %d\n", *iarg);
val = encoder->reg[0xdc];
if (*iarg)
val |= 1; /* SQUARE */
else
val &= ~1; /* !SQUARE */
- bt866_write(encoder, 0xdc, val);
+ bt866_write(client, 0xdc, val);
break;
}
@@ -236,141 +239,53 @@ static int bt866_do_command(struct bt866 *encoder,
return 0;
}
-static int bt866_write(struct bt866 *encoder,
- unsigned char subaddr, unsigned char data)
-{
- unsigned char buffer[2];
- int err;
-
- buffer[0] = subaddr;
- buffer[1] = data;
-
- encoder->reg[subaddr] = data;
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
- DEBUG(printk
- ("%s: write 0x%02X = 0x%02X\n",
- encoder->i2c->name, subaddr, data));
+I2C_CLIENT_INSMOD;
- for (err = 0; err < 3;) {
- if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
- break;
- err++;
- printk(KERN_WARNING "%s: I/O error #%d "
- "(write 0x%02x/0x%02x)\n",
- encoder->i2c->name, err, encoder->addr, subaddr);
- schedule_timeout_interruptible(msecs_to_jiffies(100));
- }
- if (err == 3) {
- printk(KERN_WARNING "%s: giving up\n",
- encoder->i2c->name);
- return -1;
- }
-
- return 0;
-}
-
-static int bt866_attach(struct i2c_adapter *adapter);
-static int bt866_detach(struct i2c_client *client);
-static int bt866_command(struct i2c_client *client,
- unsigned int cmd, void *arg);
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END};
-static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-
-static struct i2c_client_address_data addr_data = {
- normal_i2c,
- probe,
- ignore,
-};
-
-static struct i2c_driver i2c_driver_bt866 = {
- .driver.name = BT866_DEVNAME,
- .id = I2C_DRIVERID_BT866,
- .attach_adapter = bt866_attach,
- .detach_client = bt866_detach,
- .command = bt866_command
-};
-
-
-static struct i2c_client bt866_client_tmpl =
-{
- .name = "(nil)",
- .addr = 0,
- .adapter = NULL,
- .driver = &i2c_driver_bt866,
-};
-
-static int bt866_found_proc(struct i2c_adapter *adapter,
- int addr, int kind)
+static int bt866_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct bt866 *encoder;
- struct i2c_client *client;
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL)
- return -ENOMEM;
- memcpy(client, &bt866_client_tmpl, sizeof(*client));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
i2c_set_clientdata(client, encoder);
- client->adapter = adapter;
- client->addr = addr;
- sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
-
- encoder->i2c = client;
- encoder->addr = addr;
- //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
-
- /* initialize */
-
- i2c_attach_client(client);
-
return 0;
}
-static int bt866_attach(struct i2c_adapter *adapter)
+static int bt866_remove(struct i2c_client *client)
{
- if (adapter->id == I2C_HW_B_ZR36067)
- return i2c_probe(adapter, &addr_data, bt866_found_proc);
+ kfree(i2c_get_clientdata(client));
return 0;
}
-static int bt866_detach(struct i2c_client *client)
+static int bt866_legacy_probe(struct i2c_adapter *adapter)
{
- struct bt866 *encoder = i2c_get_clientdata(client);
-
- i2c_detach_client(client);
- kfree(encoder);
- kfree(client);
-
- return 0;
+ return adapter->id == I2C_HW_B_ZR36067;
}
-static int bt866_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
-{
- struct bt866 *encoder = i2c_get_clientdata(client);
- return bt866_do_command(encoder, cmd, arg);
-}
-
-static int __devinit bt866_init(void)
-{
- i2c_add_driver(&i2c_driver_bt866);
- return 0;
-}
-
-static void __devexit bt866_exit(void)
-{
- i2c_del_driver(&i2c_driver_bt866);
-}
-
-module_init(bt866_init);
-module_exit(bt866_exit);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id bt866_id[] = {
+ { "bt866", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bt866_id);
+#endif
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "bt866",
+ .driverid = I2C_DRIVERID_BT866,
+ .command = bt866_command,
+ .probe = bt866_probe,
+ .remove = bt866_remove,
+ .legacy_probe = bt866_legacy_probe,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = bt866_id,
+#endif
+};
diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c
index c050cd2ce..6fc69988a 100644
--- a/linux/drivers/media/video/cx23885/cx23885-core.c
+++ b/linux/drivers/media/video/cx23885/cx23885-core.c
@@ -644,6 +644,17 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p
port->mpegq.timeout.data = (unsigned long)port;
init_timer(&port->mpegq.timeout);
+ mutex_init(&port->frontends.lock);
+ INIT_LIST_HEAD(&port->frontends.frontend.felist);
+ port->frontends.active_fe_id = 0;
+
+ /* This should be hardcoded allow a single frontend
+ * attachment to this tsport, keeping the -dvb.c
+ * code clean and safe.
+ */
+ if(!port->num_frontends)
+ port->num_frontends = 1;
+
switch(portno) {
case 1:
port->reg_gpcnt = VID_B_GPCNT;
diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c
index 1909ef6e3..9b96b0600 100644
--- a/linux/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c
@@ -313,19 +313,25 @@ static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
struct cx23885_i2c *i2c_bus = NULL;
+ struct videobuf_dvb_frontend *fe0;
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
/* init struct videobuf_dvb */
- port->dvb.name = dev->name;
+ fe0->dvb.name = dev->name;
/* init frontend */
switch (dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1250:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_generic_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(mt2131_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(mt2131_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_generic_tunerconfig, 0);
}
@@ -334,27 +340,27 @@ static int dvb_register(struct cx23885_tsport *port)
i2c_bus = &dev->i2c_bus[0];
switch (alt_tuner) {
case 1:
- port->dvb.frontend =
+ fe0->dvb.frontend =
dvb_attach(s5h1409_attach,
&hauppauge_ezqam_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
&dev->i2c_bus[1].i2c_adap, 0x42,
&tda829x_no_probe);
- dvb_attach(tda18271_attach, port->dvb.frontend,
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
0x60, &dev->i2c_bus[1].i2c_adap,
&hauppauge_tda18271_config);
}
break;
case 0:
default:
- port->dvb.frontend =
+ fe0->dvb.frontend =
dvb_attach(s5h1409_attach,
&hauppauge_generic_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL)
- dvb_attach(mt2131_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL)
+ dvb_attach(mt2131_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_generic_tunerconfig, 0);
break;
@@ -362,42 +368,42 @@ static int dvb_register(struct cx23885_tsport *port)
break;
case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1800lp_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(mt2131_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(mt2131_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_generic_tunerconfig, 0);
}
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_5_express,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap, 0x61,
TUNER_LG_TDVS_H06XF);
}
break;
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
i2c_bus = &dev->i2c_bus[1];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1500q_config,
&dev->i2c_bus[0].i2c_adap);
- if (port->dvb.frontend != NULL)
- dvb_attach(xc5000_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL)
+ dvb_attach(xc5000_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_hvr1500q_tunerconfig);
break;
case CX23885_BOARD_HAUPPAUGE_HVR1500:
i2c_bus = &dev->i2c_bus[1];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1500_config,
&dev->i2c_bus[0].i2c_adap);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &i2c_bus->i2c_adap,
@@ -410,7 +416,7 @@ static int dvb_register(struct cx23885_tsport *port)
};
fe = dvb_attach(xc2028_attach,
- port->dvb.frontend, &cfg);
+ fe0->dvb.frontend, &cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
@@ -418,24 +424,24 @@ static int dvb_register(struct cx23885_tsport *port)
case CX23885_BOARD_HAUPPAUGE_HVR1200:
case CX23885_BOARD_HAUPPAUGE_HVR1700:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(tda10048_attach,
+ fe0->dvb.frontend = dvb_attach(tda10048_attach,
&hauppauge_hvr1200_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
&dev->i2c_bus[1].i2c_adap, 0x42,
&tda829x_no_probe);
- dvb_attach(tda18271_attach, port->dvb.frontend,
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
0x60, &dev->i2c_bus[1].i2c_adap,
&hauppauge_hvr1200_tuner_config);
}
break;
case CX23885_BOARD_HAUPPAUGE_HVR1400:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(dib7000p_attach,
+ fe0->dvb.frontend = dvb_attach(dib7000p_attach,
&i2c_bus->i2c_adap,
0x12, &hauppauge_hvr1400_dib7000_config);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &dev->i2c_bus[1].i2c_adap,
@@ -450,7 +456,7 @@ static int dvb_register(struct cx23885_tsport *port)
};
fe = dvb_attach(xc2028_attach,
- port->dvb.frontend, &cfg);
+ fe0->dvb.frontend, &cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
@@ -458,25 +464,25 @@ static int dvb_register(struct cx23885_tsport *port)
case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
i2c_bus = &dev->i2c_bus[port->nr - 1];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&dvico_s5h1409_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend == NULL)
- port->dvb.frontend = dvb_attach(s5h1411_attach,
+ if (fe0->dvb.frontend == NULL)
+ fe0->dvb.frontend = dvb_attach(s5h1411_attach,
&dvico_s5h1411_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL)
- dvb_attach(xc5000_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL)
+ dvb_attach(xc5000_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&dvico_xc5000_tunerconfig);
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
i2c_bus = &dev->i2c_bus[port->nr - 1];
- port->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &i2c_bus->i2c_adap,
@@ -488,7 +494,7 @@ static int dvb_register(struct cx23885_tsport *port)
.demod = XC3028_FE_ZARLINK456,
};
- fe = dvb_attach(xc2028_attach, port->dvb.frontend,
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
&cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
@@ -498,10 +504,10 @@ static int dvb_register(struct cx23885_tsport *port)
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &dev->i2c_bus[1].i2c_adap,
@@ -513,7 +519,7 @@ static int dvb_register(struct cx23885_tsport *port)
.demod = XC3028_FE_ZARLINK456,
};
- fe = dvb_attach(xc2028_attach, port->dvb.frontend,
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
&cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
@@ -524,43 +530,70 @@ static int dvb_register(struct cx23885_tsport *port)
dev->name);
break;
}
- if (NULL == port->dvb.frontend) {
+ if (NULL == fe0->dvb.frontend) {
printk("%s: frontend initialization failed\n", dev->name);
return -1;
}
/* define general-purpose callback pointer */
- port->dvb.frontend->callback = cx23885_tuner_callback;
+ fe0->dvb.frontend->callback = cx23885_tuner_callback;
/* Put the analog decoder in standby to keep it quiet */
cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
- if (port->dvb.frontend->ops.analog_ops.standby)
- port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend);
+ if (fe0->dvb.frontend->ops.analog_ops.standby)
+ fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
/* register everything */
- return videobuf_dvb_register(&port->dvb, THIS_MODULE, port,
- &dev->pci->dev, adapter_nr);
+ return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+ &dev->pci->dev, adapter_nr, 0);
+
}
int cx23885_dvb_register(struct cx23885_tsport *port)
{
+
+ struct videobuf_dvb_frontend *fe0;
struct cx23885_dev *dev = port->dev;
- int err;
+ int err, i;
+
+ /* Here we need to allocate the correct number of frontends,
+ * as reflected in the cards struct. The reality is that currrently
+ * no cx23885 boards support this - yet. But, if we don't modify this
+ * code then the second frontend would never be allocated (later)
+ * and fail with error before the attach in dvb_register().
+ * Without these changes we risk an OOPS later. The changes here
+ * are for safety, and should provide a good foundation for the
+ * future addition of any multi-frontend cx23885 based boards.
+ */
+ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
+ port->num_frontends);
- dprintk(1, "%s\n", __func__);
- dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
- dev->board,
- dev->name,
- dev->pci_bus,
- dev->pci_slot);
+ for (i = 1; i <= port->num_frontends; i++) {
+ if (videobuf_dvb_alloc_frontend(dev, &port->frontends, i) == NULL) {
+ printk(KERN_ERR "%s() failed to alloc\n", __func__);
+ return -ENOMEM;
+ }
- err = -ENODEV;
+ fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
+ if (!fe0)
+ err = -EINVAL;
- /* dvb stuff */
- printk("%s: cx23885 based dvb card\n", dev->name);
- videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock,
+ dprintk(1, "%s\n", __func__);
+ dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
+ dev->board,
+ dev->name,
+ dev->pci_bus,
+ dev->pci_slot);
+
+ err = -ENODEV;
+
+ /* dvb stuff */
+ /* We have to init the queue for each frontend on a port. */
+ printk("%s: cx23885 based dvb card\n", dev->name);
+ videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
sizeof(struct cx23885_buffer), port);
+ }
err = dvb_register(port);
if (err != 0)
printk("%s() dvb_register failed err = %d\n", __func__, err);
@@ -570,9 +603,18 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
int cx23885_dvb_unregister(struct cx23885_tsport *port)
{
- /* dvb */
- if(port->dvb.frontend)
- videobuf_dvb_unregister(&port->dvb);
+ struct videobuf_dvb_frontend *fe0;
+
+ /* FIXME: in an error condition where the we have
+ * an expected number of frontends (attach problem)
+ * then this might not clean up correctly, if 1
+ * is invalid.
+ * This comment only applies to future boards IF they
+ * implement MFE support.
+ */
+ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+ if(fe0->dvb.frontend)
+ videobuf_dvb_unregister_bus(&port->frontends);
return 0;
}
diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h
index dea1798f7..2dde9e01a 100644
--- a/linux/drivers/media/video/cx23885/cx23885.h
+++ b/linux/drivers/media/video/cx23885/cx23885.h
@@ -226,7 +226,7 @@ struct cx23885_tsport {
int nr;
int sram_chno;
- struct videobuf_dvb dvb;
+ struct videobuf_dvb_frontends frontends;
/* dma queues */
struct cx23885_dmaqueue mpegq;
@@ -263,6 +263,9 @@ struct cx23885_tsport {
u32 src_sel_val;
u32 vld_misc_val;
u32 hw_sop_ctrl_val;
+
+ /* Allow a single tsport to have multiple frontends */
+ u32 num_frontends;
};
struct cx23885_dev {
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index a351a2220..eac3508d6 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -1303,27 +1303,36 @@ static const struct cx88_board cx88_boards[] = {
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_HAUPPAUGE_HVR3000] = {
- /* FIXME: Add dvb & radio support */
.name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
.tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
+ .audio_chip = V4L2_IDENT_WM8775,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x84bf,
+ .audioroute = 1,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0x84bf,
+ .audioroute = 2,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0x84bf,
+ .audioroute = 2,
}},
+ /* FIXME Radio tunes but only noise is heard */
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x84bf,
+ },
.mpeg = CX88_MPEG_DVB,
+ .num_frontends = 2,
},
[CX88_BOARD_NORWOOD_MICRO] = {
.name = "Norwood Micro TV Tuner",
@@ -1749,6 +1758,7 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
+ .audio_chip = V4L2_IDENT_WM8775,
/*
* GPIO0 (WINTV2000)
*
@@ -1762,7 +1772,7 @@ static const struct cx88_board cx88_boards[] = {
* BIT VALUE FUNCTION GP{x}_IO
* 0 1 I:?
* 1 1 I:?
- * 2 1 O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH
+ * 2 1 O:MPEG PORT 0=DVB-T 1=DVB-S
* 3 1 I:?
* 4 1 I:?
* 5 1 I:?
@@ -1783,17 +1793,25 @@ static const struct cx88_board cx88_boards[] = {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0xc4bf,
+ .audioroute = 1,
}, {
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0xc4bf,
+ .audioroute = 2,
}, {
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0xc4bf,
+ .audioroute = 2,
} },
- /* fixme: Add radio support */
+ /* FIXME Radio tunes but only noise is heard */
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0xc4bf,
+ },
.mpeg = CX88_MPEG_DVB,
+ .num_frontends = 2,
},
[CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
.name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
@@ -2695,10 +2713,13 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_HVR3000:
case CX88_BOARD_HAUPPAUGE_HVR4000:
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
/* Init GPIO */
cx_write(MO_GP0_IO, core->board.input[0].gpio0);
udelay(1000);
+ cx_clear(MO_GP0_IO, 0x00000080);
+ udelay(50);
+ cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
+ udelay(1000);
break;
}
}
@@ -3037,10 +3058,14 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
- info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ if (!core->board.num_frontends)
+ core->board.num_frontends=1;
+
+ info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
pci->subsystem_vendor, pci->subsystem_device, core->board.name,
core->boardnr, card[core->nr] == core->boardnr ?
- "insmod option" : "autodetected");
+ "insmod option" : "autodetected",
+ core->board.num_frontends);
if (tuner[core->nr] != UNSET)
core->board.tuner_type = tuner[core->nr];
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c
index 84f235ba0..1a0f971c6 100644
--- a/linux/drivers/media/video/cx88/cx88-dvb.c
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c
@@ -117,13 +117,23 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
struct cx8802_dev *dev= fe->dvb->priv;
struct cx8802_driver *drv = NULL;
int ret = 0;
+ int fe_id;
+
+ fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
+ if (!fe_id) {
+ printk(KERN_ERR "%s() No frontend found\n", __FUNCTION__);
+ return -EINVAL;
+ }
drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
if (drv) {
- if (acquire)
+ if (acquire){
+ dev->frontends.active_fe_id = fe_id;
ret = drv->request_acquire(drv);
- else
+ } else {
ret = drv->request_release(drv);
+ dev->frontends.active_fe_id = 0;
+ }
}
return ret;
@@ -490,6 +500,7 @@ static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
{
struct dvb_frontend *fe;
+ struct videobuf_dvb_frontend *fe0 = NULL;
struct xc2028_ctrl ctl;
struct xc2028_config cfg = {
.i2c_adap = &dev->core->i2c_adap,
@@ -497,7 +508,12 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
.ctrl = &ctl,
};
- if (!dev->dvb.frontend) {
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
+
+ if (!fe0->dvb.frontend) {
printk(KERN_ERR "%s/2: dvb frontend not attached. "
"Can't attach xc3028\n",
dev->core->name);
@@ -511,10 +527,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
*/
cx88_setup_xc3028(dev->core, &ctl);
- fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
if (!fe) {
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->core->name);
+ dvb_frontend_detach(fe0->dvb.frontend);
+ dvb_unregister_frontend(fe0->dvb.frontend);
+ fe0->dvb.frontend = NULL;
return -EINVAL;
}
@@ -539,8 +558,10 @@ static int cx24116_reset_device(struct dvb_frontend *fe)
struct cx88_core *core = dev->core;
/* Reset the part */
+ /* Put the cx24116 into reset */
cx_write(MO_SRST_IO, 0);
msleep(10);
+ /* Take the cx24116 out of reset */
cx_write(MO_SRST_IO, 1);
msleep(10);
@@ -581,19 +602,25 @@ static struct stv0288_config tevii_tuner_earda_config = {
static int dvb_register(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
+ struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+ int mfe_shared = 0; /* bus not shared by default */
- /* init struct videobuf_dvb */
- dev->dvb.name = core->name;
- dev->ts_gen_cntrl = 0x0c;
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
- /* init frontend */
+ /* multi-frontend gate control is undefined or defaults to fe0 */
+ dev->frontends.gate = 0;
+
+ /* init frontend(s) */
switch (core->boardnr) {
case CX88_BOARD_HAUPPAUGE_DVB_T1:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
+ fe0->dvb.frontend = dvb_attach(cx22702_attach,
&connexant_refboard_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, &core->i2c_adap,
DVB_PLL_THOMSON_DTT759X))
goto frontend_detach;
@@ -603,11 +630,11 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_CONEXANT_DVB_T1:
case CX88_BOARD_KWORLD_DVB_T_CX22702:
case CX88_BOARD_WINFAST_DTV1000:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
+ fe0->dvb.frontend = dvb_attach(cx22702_attach,
&connexant_refboard_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x60, &core->i2c_adap,
DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
@@ -617,33 +644,67 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_HAUPPAUGE_HVR1100:
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
case CX88_BOARD_HAUPPAUGE_HVR1300:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
+ fe0->dvb.frontend = dvb_attach(cx22702_attach,
&hauppauge_hvr_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_PHILIPS_FMD1216ME_MK3))
goto frontend_detach;
}
break;
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ /* DVB-S init */
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
+ &hauppauge_novas_config,
+ &dev->core->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
+ &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
+ dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __FUNCTION__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __FUNCTION__);
+ }
+ /* DVB-T init */
+ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
+ if (fe1) {
+ dev->frontends.gate = 2;
+ mfe_shared = 1;
+ fe1->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr_config,
+ &dev->core->i2c_adap);
+ if (fe1->dvb.frontend) {
+ fe1->dvb.frontend->id = 1;
+ if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
+ &dev->core->i2c_adap, 0x61,
+ TUNER_PHILIPS_FMD1216ME_MK3)) {
+ dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __FUNCTION__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __FUNCTION__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
+ }
+ break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x60, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
break;
}
/* ZL10353 replaces MT352 on later cards */
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_plus_v1_1,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x60, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
}
@@ -651,31 +712,31 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
/* The tin box says DEE1601, but it seems to be DTT7579
* compatible, with a slightly different MT352 AGC gain. */
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv_dual,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
break;
}
/* ZL10353 replaces MT352 on later cards */
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_plus_v1_1,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_LG_Z201))
goto frontend_detach;
}
@@ -683,11 +744,11 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_KWORLD_DVB_T:
case CX88_BOARD_DNTV_LIVE_DVB_T:
case CX88_BOARD_ADSTECH_DVB_T_PCI:
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dntv_live_dvbt_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_UNKNOWN_1))
goto frontend_detach;
}
@@ -695,10 +756,10 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
/* MT352 is on a secondary I2C bus made from some GPIO lines */
- dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
+ fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
&dev->vp3054->adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_PHILIPS_FMD1216ME_MK3))
goto frontend_detach;
@@ -709,22 +770,22 @@ static int dvb_register(struct cx8802_dev *dev)
#endif
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_hybrid,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_THOMSON_FE6600))
goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
&core->i2c_adap);
- if (dev->dvb.frontend == NULL)
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ if (fe0->dvb.frontend == NULL)
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv_mt352_xc3028,
&core->i2c_adap);
/*
@@ -732,16 +793,16 @@ static int dvb_register(struct cx8802_dev *dev)
* We must not permit gate_ctrl to be performed, or
* the xc3028 cannot communicate on the bus.
*/
- if (dev->dvb.frontend)
- dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+ if (fe0->dvb.frontend)
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
if (attach_xc3028(0x61, dev) < 0)
return -EINVAL;
break;
case CX88_BOARD_PCHDTV_HD3000:
- dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
+ fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_THOMSON_DTT761X))
goto frontend_detach;
@@ -758,11 +819,11 @@ static int dvb_register(struct cx8802_dev *dev)
/* Select RF connector callback */
fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_3_gold,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_MICROTUNE_4042FI5))
goto frontend_detach;
@@ -776,11 +837,11 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 9);
mdelay(200);
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_3_gold,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_THOMSON_DTT761X))
goto frontend_detach;
@@ -794,15 +855,15 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_5_gold,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_LG_TDVS_H06XF))
goto frontend_detach;
- if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+ if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x43))
goto frontend_detach;
}
@@ -815,25 +876,25 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&pchdtv_hd5500,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_LG_TDVS_H06XF))
goto frontend_detach;
- if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+ if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x43))
goto frontend_detach;
}
break;
case CX88_BOARD_ATI_HDTVWONDER:
- dev->dvb.frontend = dvb_attach(nxt200x_attach,
+ fe0->dvb.frontend = dvb_attach(nxt200x_attach,
&ati_hdtvwonder,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_PHILIPS_TUV1236D))
goto frontend_detach;
@@ -841,49 +902,49 @@ static int dvb_register(struct cx8802_dev *dev)
break;
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- dev->dvb.frontend = dvb_attach(cx24123_attach,
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
&hauppauge_novas_config,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
goto frontend_detach;
}
break;
case CX88_BOARD_KWORLD_DVBS_100:
- dev->dvb.frontend = dvb_attach(cx24123_attach,
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
&kworld_dvbs_100_config,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
+ if (fe0->dvb.frontend) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
}
break;
case CX88_BOARD_GENIATECH_DVBS:
- dev->dvb.frontend = dvb_attach(cx24123_attach,
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
&geniatech_dvbs_config,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
+ if (fe0->dvb.frontend) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
}
break;
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&pinnacle_pctv_hd_800i_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
&core->i2c_adap,
&pinnacle_pctv_hd_800i_tuner_config))
goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&dvico_hdtv5_pci_nano_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &core->i2c_adap,
@@ -896,17 +957,17 @@ static int dvb_register(struct cx8802_dev *dev)
};
fe = dvb_attach(xc2028_attach,
- dev->dvb.frontend, &cfg);
+ fe0->dvb.frontend, &cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
case CX88_BOARD_PINNACLE_HYBRID_PCTV:
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&cx88_pinnacle_hybrid_pctv,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
if (attach_xc3028(0x61, dev) < 0)
goto frontend_detach;
}
@@ -914,85 +975,118 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_GENIATECH_X8000_MT:
dev->ts_gen_cntrl = 0x00;
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&cx88_geniatech_x8000_mt,
&core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
goto frontend_detach;
break;
case CX88_BOARD_KWORLD_ATSC_120:
- dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&kworld_atsc_120_config,
&core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
goto frontend_detach;
break;
case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
- dev->dvb.frontend = dvb_attach(s5h1411_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1411_attach,
&dvico_fusionhdtv7_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
&core->i2c_adap,
&dvico_fusionhdtv7_tuner_config))
goto frontend_detach;
}
break;
case CX88_BOARD_HAUPPAUGE_HVR4000:
+ /* DVB-S/S2 Init */
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &hauppauge_hvr4000_config,
+ &dev->core->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if(!dvb_attach(isl6421_attach, fe0->dvb.frontend,
+ &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
+ dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __FUNCTION__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __FUNCTION__);
+ }
+ /* DVB-T Init */
+ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
+ if (fe1) {
+ dev->frontends.gate = 2;
+ mfe_shared = 1;
+ fe1->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr_config,
+ &dev->core->i2c_adap);
+ if (fe1->dvb.frontend) {
+ fe1->dvb.frontend->id = 1;
+ if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
+ &dev->core->i2c_adap, 0x61,
+ TUNER_PHILIPS_FMD1216ME_MK3)) {
+ dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __FUNCTION__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __FUNCTION__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
+ }
+ break;
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- /* Support for DVB-S only, not DVB-T support */
- dev->dvb.frontend = dvb_attach(cx24116_attach,
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
&hauppauge_hvr4000_config,
&dev->core->i2c_adap);
- if (dev->dvb.frontend) {
- dvb_attach(isl6421_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ dvb_attach(isl6421_attach, fe0->dvb.frontend,
&dev->core->i2c_adap,
0x08, ISL6421_DCL, 0x00);
}
break;
case CX88_BOARD_TEVII_S420:
- dev->dvb.frontend = dvb_attach(stv0299_attach,
+ fe0->dvb.frontend = dvb_attach(stv0299_attach,
&tevii_tuner_sharp_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
&core->i2c_adap, DVB_PLL_OPERA1))
goto frontend_detach;
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
} else {
- dev->dvb.frontend = dvb_attach(stv0288_attach,
+ fe0->dvb.frontend = dvb_attach(stv0288_attach,
&tevii_tuner_earda_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
&core->i2c_adap))
goto frontend_detach;
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
}
}
break;
case CX88_BOARD_TEVII_S460:
- dev->dvb.frontend = dvb_attach(cx24116_attach,
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
&tevii_s460_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ if (fe0->dvb.frontend != NULL) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
}
break;
case CX88_BOARD_OMICOM_SS4_PCI:
case CX88_BOARD_TBS_8920:
case CX88_BOARD_PROF_7300:
- dev->dvb.frontend = dvb_attach(cx24116_attach,
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
&hauppauge_hvr4000_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ if (fe0->dvb.frontend != NULL) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
}
break;
default:
@@ -1000,29 +1094,32 @@ static int dvb_register(struct cx8802_dev *dev)
core->name);
break;
}
- if (NULL == dev->dvb.frontend) {
+
+ if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
printk(KERN_ERR
"%s/2: frontend initialization failed\n",
core->name);
return -EINVAL;
}
/* define general-purpose callback pointer */
- dev->dvb.frontend->callback = cx88_tuner_callback;
+ fe0->dvb.frontend->callback = cx88_tuner_callback;
/* Ensure all frontends negotiate bus access */
- dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+ fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+ if (fe1)
+ fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
/* register everything */
- return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
- &dev->pci->dev, adapter_nr);
+ return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+ &dev->pci->dev, adapter_nr, mfe_shared);
frontend_detach:
- if (dev->dvb.frontend) {
- dvb_frontend_detach(dev->dvb.frontend);
- dev->dvb.frontend = NULL;
+ if (fe0->dvb.frontend) {
+ dvb_frontend_detach(fe0->dvb.frontend);
+ fe0->dvb.frontend = NULL;
}
return -EINVAL;
}
@@ -1046,6 +1143,38 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
cx_clear(MO_GP0_IO, 0x00000004);
udelay(1000);
break;
+
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ case CX88_BOARD_HAUPPAUGE_HVR4000:
+ if(core->dvbdev->frontends.active_fe_id == 1) {
+ /* DVB-S/S2 Enabled */
+
+ /* Toggle reset on cx22702 leaving i2c active */
+ cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080);
+ udelay(1000);
+ cx_clear(MO_GP0_IO, 0x00000080);
+ udelay(50);
+ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
+ cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
+ udelay(1000);
+
+ cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
+ core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
+ } else
+ if (core->dvbdev->frontends.active_fe_id == 2) {
+ /* DVB-T Enabled */
+
+ /* Put the cx24116/cx24123 into reset */
+ cx_write(MO_SRST_IO, 0);
+
+ /* cx22702 out of reset and enable it */
+ cx_set(MO_GP0_IO, 0x00000080);
+ cx_clear(MO_GP0_IO, 0x00000004);
+ core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
+ udelay(1000);
+ }
+ break;
+
default:
err = -ENODEV;
}
@@ -1066,6 +1195,9 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
cx_set(MO_GP0_IO, 0x00000004);
#endif
break;
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ case CX88_BOARD_HAUPPAUGE_HVR4000:
+ break;
default:
err = -ENODEV;
}
@@ -1076,7 +1208,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
struct cx8802_dev *dev = drv->core->dvbdev;
- int err;
+ int err, i;
+ struct videobuf_dvb_frontend *fe;
dprintk( 1, "%s\n", __func__);
dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1096,18 +1229,28 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
/* dvb stuff */
printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
- videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops,
+ dev->ts_gen_cntrl = 0x0c;
+
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+ if (!fe) {
+ printk(KERN_ERR "%s() failed to get frontend(%d)\n", __FUNCTION__, i);
+ continue;
+ }
+ videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP,
sizeof(struct cx88_buffer),
dev);
+ /* init struct videobuf_dvb */
+ fe->dvb.name = dev->core->name;
+ }
err = dvb_register(dev);
if (err != 0)
printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
core->name, err);
-
- fail_core:
+fail_core:
return err;
}
@@ -1115,9 +1258,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv)
{
struct cx8802_dev *dev = drv->core->dvbdev;
- /* dvb */
- if (dev->dvb.frontend)
- videobuf_dvb_unregister(&dev->dvb);
+ videobuf_dvb_unregister_bus(&dev->frontends);
vp3054_i2c_remove(dev);
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index 8e74d64fd..01de23007 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -116,18 +116,25 @@ static int detach_inform(struct i2c_client *client)
void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
{
+ struct videobuf_dvb_frontends *f = &core->dvbdev->frontends;
+ struct videobuf_dvb_frontend *fe = NULL;
if (0 != core->i2c_rc)
return;
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
- if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
- if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
- core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
+ if (core->dvbdev && f) {
+ if(f->gate <= 1) /* undefined or fe0 */
+ fe = videobuf_dvb_get_frontend(f, 1);
+ else
+ fe = videobuf_dvb_get_frontend(f, f->gate);
+
+ if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
+ fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1);
i2c_clients_command(&core->i2c_adap, cmd, arg);
- if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
- core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
+ if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
+ fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0);
} else
#endif
i2c_clients_command(&core->i2c_adap, cmd, arg);
diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c
index 4af6604ec..88c237790 100644
--- a/linux/drivers/media/video/cx88/cx88-mpeg.c
+++ b/linux/drivers/media/video/cx88/cx88-mpeg.c
@@ -808,7 +808,8 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
{
struct cx8802_dev *dev;
struct cx88_core *core;
- int err;
+ struct videobuf_dvb_frontend *demod;
+ int err,i;
/* general setup */
core = cx88_core_get(pci_dev);
@@ -821,6 +822,11 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
if (!core->board.mpeg)
goto fail_core;
+ if (!core->board.num_frontends) {
+ printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __FUNCTION__, err);
+ goto fail_core;
+ }
+
err = -ENOMEM;
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
if (NULL == dev)
@@ -835,6 +841,20 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
INIT_LIST_HEAD(&dev->drvlist);
list_add_tail(&dev->devlist,&cx8802_devlist);
+ mutex_init(&dev->frontends.lock);
+ INIT_LIST_HEAD(&dev->frontends.frontend.felist);
+
+ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __FUNCTION__, core->board.num_frontends);
+
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ demod = videobuf_dvb_alloc_frontend(dev, &dev->frontends, i);
+ if(demod == NULL) {
+ printk(KERN_ERR "%s() failed to alloc\n", __FUNCTION__);
+ err = -ENOMEM;
+ goto fail_free;
+ }
+ }
+
/* Maintain a reference so cx88-video can query the 8802 device. */
core->dvbdev = dev;
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index 778e1f707..774c0b9b1 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -248,7 +248,7 @@ struct cx88_input {
enum cx88_itype type;
u32 gpio0, gpio1, gpio2, gpio3;
unsigned int vmux:2;
- unsigned int audioroute:2;
+ unsigned int audioroute:4;
};
struct cx88_board {
@@ -262,6 +262,7 @@ struct cx88_board {
struct cx88_input radio;
enum cx88_board_type mpeg;
unsigned int audio_chip;
+ int num_frontends;
};
struct cx88_subid {
@@ -360,6 +361,7 @@ struct cx88_core {
struct cx8802_dev *dvbdev;
enum cx88_board_type active_type_id;
int active_ref;
+ int active_fe_id;
};
struct cx8800_dev;
@@ -511,7 +513,7 @@ struct cx8802_dev {
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
/* for dvb only */
- struct videobuf_dvb dvb;
+ struct videobuf_dvb_frontends frontends;
#endif
#if defined(CONFIG_VIDEO_CX88_VP3054) || \
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_bridge.h b/linux/drivers/media/video/gspca/m5602/m5602_bridge.h
index c786d7d3d..1a37ae4bc 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -1,7 +1,7 @@
/*
* USB Driver for ALi m5602 based webcams
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -25,33 +25,6 @@
/*****************************************************************************/
-#undef PDEBUG
-#undef info
-#undef err
-
-#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \
- format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \
- format "\n" , ## arg)
-
-/* Debug parameters */
-#define DBG_INIT 0x1
-#define DBG_PROBE 0x2
-#define DBG_V4L2 0x4
-#define DBG_TRACE 0x8
-#define DBG_DATA 0x10
-#define DBG_V4L2_CID 0x20
-#define DBG_GSPCA 0x40
-
-#define PDEBUG(level, fmt, args...) \
- do { \
- if (m5602_debug & level) \
- info("[%s:%d] " fmt, __func__, __LINE__ , \
- ## args); \
- } while (0)
-
-/*****************************************************************************/
-
#define M5602_XB_SENSOR_TYPE 0x00
#define M5602_XB_SENSOR_CTRL 0x01
#define M5602_XB_LINE_OF_FRAME_H 0x02
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_core.c b/linux/drivers/media/video/gspca/m5602/m5602_core.c
index 19d5e351c..fd6ce384b 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_core.c
@@ -1,7 +1,7 @@
-/*
+ /*
* USB Driver for ALi m5602 based webcams
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -26,7 +26,6 @@
int force_sensor;
int dump_bridge;
int dump_sensor;
-unsigned int m5602_debug;
static const __devinitdata struct usb_device_id m5602_table[] = {
{USB_DEVICE(0x0402, 0x5602)},
@@ -48,7 +47,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
1, M5602_URB_MSG_TIMEOUT);
*i2c_data = buf[0];
- PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x",
+ PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x",
address, *i2c_data);
/* usb_control_msg(...) returns the number of bytes sent upon success,
@@ -63,7 +62,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
struct usb_device *udev = sd->gspca_dev.dev;
__u8 *buf = sd->gspca_dev.usb_buf;
- PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x",
address, i2c_data);
memcpy(buf, bridge_urb_skeleton,
@@ -91,7 +90,8 @@ static void m5602_dump_bridge(struct sd *sd)
m5602_read_bridge(sd, i, &val);
info("ALi m5602 address 0x%x contains 0x%x", i, val);
}
- info("Warning: The camera probably won't work until it's power cycled");
+ info("Warning: The ALi m5602 webcam probably won't work "
+ "until it's power cycled");
}
static int m5602_probe_sensor(struct sd *sd)
@@ -135,7 +135,7 @@ static int m5602_init(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int err;
- PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam");
+ PDEBUG(D_CONF, "Initializing ALi m5602 webcam");
/* Run the init sequence */
err = sd->sensor->init(sd);
@@ -146,16 +146,18 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
__u8 *buf = sd->gspca_dev.usb_buf;
+ int err;
/* Send start command to the camera */
const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
memcpy(buf, buffer, sizeof(buffer));
- usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x04, 0x40, 0x19, 0x0000, buf,
- 4, M5602_URB_MSG_TIMEOUT);
+ err = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x04, 0x40, 0x19, 0x0000, buf,
+ 4, M5602_URB_MSG_TIMEOUT);
- PDEBUG(DBG_V4L2, "Transfer started");
- return 0;
+ PDEBUG(D_STREAM, "Transfer started");
+ return (err < 0) ? err : 0;
}
static void m5602_urb_complete(struct gspca_dev *gspca_dev,
@@ -165,14 +167,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
if (len < 6) {
- PDEBUG(DBG_DATA, "Packet is less than 6 bytes");
+ PDEBUG(D_PACK, "Packet is less than 6 bytes");
return;
}
/* Frame delimiter: ff xx xx xx ff ff */
if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
data[2] != sd->frame_id) {
- PDEBUG(DBG_DATA, "Frame delimiter detected");
+ PDEBUG(D_FRAM, "Frame delimiter detected");
sd->frame_id = data[2];
/* Remove the extra fluff appended on each header */
@@ -187,7 +189,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
/* Create a new frame */
gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
- PDEBUG(DBG_V4L2, "Starting new frame %d",
+ PDEBUG(D_FRAM, "Starting new frame %d",
sd->frame_count);
} else {
@@ -198,7 +200,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
len -= 4;
if (cur_frame_len + len <= frame->v4l2_buf.length) {
- PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes",
+ PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
sd->frame_count, len);
gspca_frame_add(gspca_dev, INTER_PACKET, frame,
@@ -234,8 +236,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
struct cam *cam;
int err;
- PDEBUG(DBG_GSPCA, "m5602_configure start");
-
cam = &gspca_dev->cam;
cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
sd->desc = &sd_desc;
@@ -248,11 +248,10 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
if (err)
goto fail;
- PDEBUG(DBG_GSPCA, "m5602_configure end");
return 0;
fail:
- PDEBUG(DBG_GSPCA, "m5602_configure failed");
+ PDEBUG(D_ERR, "ALi m5602 webcam failed");
cam->cam_mode = NULL;
cam->nmodes = 0;
@@ -282,13 +281,13 @@ static int __init mod_m5602_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "m5602 module registered");
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit mod_m5602_exit(void)
{
usb_deregister(&sd_driver);
- PDEBUG(D_PROBE, "m5602 module deregistered");
+ PDEBUG(D_PROBE, "deregistered");
}
module_init(mod_m5602_init);
@@ -297,9 +296,6 @@ module_exit(mod_m5602_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "toggles debug on/off");
-
module_param(force_sensor, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(force_sensor,
"force detection of sensor, "
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 566d4925a..fb700c2d0 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -1,7 +1,7 @@
/*
* Driver for the mt9m111 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -107,7 +107,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
*val = data[0] & MT9M111_RMB_MIRROR_ROWS;
- PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+ PDEBUG(D_V4L2, "Read vertical flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -118,7 +118,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+ PDEBUG(D_V4L2, "Set vertical flip to %d", val);
/* Set the correct page map */
err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -145,7 +145,7 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
*val = data[0] & MT9M111_RMB_MIRROR_COLS;
- PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+ PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -156,7 +156,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
+ PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
/* Set the correct page map */
err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -188,7 +188,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
((tmp & (1 << 8)) * 2) |
(tmp & 0x7f);
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -222,7 +222,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
data[1] = (tmp & 0xff00) >> 8;
data[0] = (tmp & 0xff);
- PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
+ PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
data[1], data[0]);
err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
@@ -257,7 +257,7 @@ int mt9m111_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len && !err; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x contains 0x%x ", address, *i2c_data);
}
out:
@@ -290,7 +290,7 @@ int mt9m111_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 79a5d8878..07d224d01 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -1,7 +1,7 @@
/*
* Driver for the mt9m111 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -82,7 +82,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int mt9m111_probe(struct sd *sd);
int mt9m111_init(struct sd *sd);
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_ov9650.c b/linux/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 31c589625..837c7e476 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -1,7 +1,7 @@
/*
* Driver for the ov9650 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -40,7 +40,7 @@ int ov9650_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
return (err < 0) ? err : 0;
@@ -72,7 +72,7 @@ int ov9650_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
@@ -199,7 +199,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
goto out;
*val |= (i2c_data & 0x3f) << 10;
- PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
+ PDEBUG(D_V4L2, "Read exposure %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -210,7 +210,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
- PDEBUG(DBG_V4L2_CID, "Set exposure to %d",
+ PDEBUG(D_V4L2, "Set exposure to %d",
val & 0xffff);
/* The 6 MSBs */
@@ -246,7 +246,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
*val |= i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -280,7 +280,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
+ PDEBUG(D_V4L2, "Read red gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -291,7 +291,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set red gain to %d",
+ PDEBUG(D_V4L2, "Set red gain to %d",
val & 0xff);
i2c_data = val & 0xff;
@@ -309,7 +309,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
+ PDEBUG(D_V4L2, "Read blue gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -320,7 +320,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set blue gain to %d",
+ PDEBUG(D_V4L2, "Set blue gain to %d",
val & 0xff);
i2c_data = val & 0xff;
@@ -340,7 +340,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
*val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
else
*val = (i2c_data & OV9650_HFLIP) >> 5;
- PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+ PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -351,7 +351,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
+ PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
if (err < 0)
goto out;
@@ -379,7 +379,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
*val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
else
*val = (i2c_data & 0x10) >> 4;
- PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+ PDEBUG(D_V4L2, "Read vertical flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -390,7 +390,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+ PDEBUG(D_V4L2, "Set vertical flip to %d", val);
err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
if (err < 0)
goto out;
@@ -420,7 +420,7 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
*val |= i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -431,7 +431,7 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff);
+ PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff);
/* Read the OV9650_VREF register first to avoid
corrupting the VREF high and low bits */
@@ -461,7 +461,7 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
*val = (i2c_data & OV9650_AWB_EN) >> 1;
- PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val);
+ PDEBUG(D_V4L2, "Read auto white balance %d", *val);
return (err < 0) ? err : 0;
}
@@ -472,7 +472,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val);
+ PDEBUG(D_V4L2, "Set auto white balance to %d", val);
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
goto out;
@@ -491,7 +491,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
*val = (i2c_data & OV9650_AGC_EN) >> 2;
- PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val);
+ PDEBUG(D_V4L2, "Read auto gain control %d", *val);
return (err < 0) ? err : 0;
}
@@ -502,7 +502,7 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val);
+ PDEBUG(D_V4L2, "Set auto gain control to %d", val);
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
goto out;
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h b/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h
index fb21e7ffb..e8ede47ce 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -1,7 +1,7 @@
/*
* Driver for the ov9650 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -121,7 +121,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int ov9650_probe(struct sd *sd);
int ov9650_init(struct sd *sd);
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_po1030.c b/linux/drivers/media/video/gspca/m5602/m5602_po1030.c
index 08c015bde..d17ac5256 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -1,7 +1,7 @@
/*
* Driver for the po1030 sensor
*
- * Copyright (c) 2008 Erik Andren
+ * Copyright (c) 2008 Erik Andrén
* Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -82,7 +82,7 @@ int po1030_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
return (err < 0) ? err : 0;
@@ -112,7 +112,7 @@ int po1030_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
@@ -185,7 +185,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
&i2c_data, 1);
*val |= i2c_data;
- PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val);
+ PDEBUG(D_V4L2, "Exposure read as %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -196,10 +196,10 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
- PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff);
+ PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
i2c_data = ((val & 0xff00) >> 8);
- PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x",
+ PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H,
@@ -208,7 +208,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
goto out;
i2c_data = (val & 0xff);
- PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x",
+ PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M,
&i2c_data, 1);
@@ -226,7 +226,71 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
&i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val);
+ PDEBUG(D_V4L2, "Read global gain %d", *val);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ err = po1030_read_sensor(sd, PO1030_REG_CONTROL2,
+ &i2c_data, 1);
+
+ *val = (i2c_data >> 7) & 0x01 ;
+
+ PDEBUG(D_V4L2, "Read hflip %d", *val);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ PDEBUG(D_V4L2, "Set hflip %d", val);
+
+ i2c_data = (val & 0x01) << 7;
+
+ err = po1030_write_sensor(sd, PO1030_REG_CONTROL2,
+ &i2c_data, 1);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
+ &i2c_data, 1);
+
+ *val = (i2c_data >> 6) & 0x01;
+
+ PDEBUG(D_V4L2, "Read vflip %d", *val);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ PDEBUG(D_V4L2, "Set vflip %d", val);
+
+ i2c_data = (val & 0x01) << 6;
+
+ err = po1030_write_sensor(sd, PO1030_REG_CONTROL2,
+ &i2c_data, 1);
return (err < 0) ? err : 0;
}
@@ -238,7 +302,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data);
+ PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN,
&i2c_data, 1);
return (err < 0) ? err : 0;
@@ -253,7 +317,7 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN,
&i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
+ PDEBUG(D_V4L2, "Read red gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -264,7 +328,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data);
+ PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN,
&i2c_data, 1);
return (err < 0) ? err : 0;
@@ -279,7 +343,7 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN,
&i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
+ PDEBUG(D_V4L2, "Read blue gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -290,7 +354,7 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
i2c_data = val & 0xff;
- PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data);
+ PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN,
&i2c_data, 1);
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_po1030.h b/linux/drivers/media/video/gspca/m5602/m5602_po1030.h
index 68f34c97b..a0b75ff61 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -1,8 +1,7 @@
/*
* Driver for the po1030 sensor.
- * This is probably a pixel plus sensor but we haven't identified it yet
*
- * Copyright (c) 2008 Erik Andren
+ * Copyright (c) 2008 Erik Andrén
* Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -109,10 +108,13 @@
#define PO1030_REG_YCONTRAST 0x74
#define PO1030_REG_YSATURATION 0x75
+#define PO1030_HFLIP (1 << 7)
+#define PO1030_VFLIP (1 << 6)
+
/*****************************************************************************/
#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
-#define PO1030_EXPOSURE_DEFAULT 0xf0ff
+#define PO1030_EXPOSURE_DEFAULT 0x0085
#define PO1030_BLUE_GAIN_DEFAULT 0x40
#define PO1030_RED_GAIN_DEFAULT 0x40
@@ -121,7 +123,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int po1030_probe(struct sd *sd);
int po1030_init(struct sd *sd);
@@ -142,6 +143,10 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
static struct m5602_sensor po1030 = {
.name = "PO1030",
@@ -152,7 +157,7 @@ static struct m5602_sensor po1030 = {
.init = po1030_init,
.power_down = po1030_power_down,
- .nctrls = 4,
+ .nctrls = 6,
.ctrls = {
{
{
@@ -160,7 +165,7 @@ static struct m5602_sensor po1030 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "gain",
.minimum = 0x00,
- .maximum = 0xff,
+ .maximum = 0x4f,
.step = 0x1,
.default_value = PO1030_GLOBAL_GAIN_DEFAULT,
.flags = V4L2_CTRL_FLAG_SLIDER
@@ -173,7 +178,7 @@ static struct m5602_sensor po1030 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "exposure",
.minimum = 0x00,
- .maximum = 0xffff,
+ .maximum = 0x02ff,
.step = 0x1,
.default_value = PO1030_EXPOSURE_DEFAULT,
.flags = V4L2_CTRL_FLAG_SLIDER
@@ -206,8 +211,33 @@ static struct m5602_sensor po1030 = {
},
.set = po1030_set_blue_balance,
.get = po1030_get_blue_balance
+ }, {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = po1030_set_hflip,
+ .get = po1030_get_hflip
+ }, {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = po1030_set_vflip,
+ .get = po1030_get_vflip
}
},
+
.nmodes = 1,
.modes = {
{
@@ -381,7 +411,7 @@ static const unsigned char init_po1030[][4] =
/* Set the y window to 1 */
{SENSOR, PO1030_REG_WINDOWY_H, 0x00},
- {SENSOR, PO1030_REG_WINDOWX_L, 0x01},
+ {SENSOR, PO1030_REG_WINDOWY_L, 0x01},
{SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
{SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 682025653..14b1eac5b 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -1,7 +1,7 @@
/*
* Driver for the s5k4aa sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -117,7 +117,7 @@ int s5k4aa_read_sensor(struct sd *sd, const u8 address,
for (i = 0; (i < len) & !err; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
out:
@@ -150,7 +150,7 @@ int s5k4aa_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
@@ -248,7 +248,7 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
*val = data << 8;
err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
*val |= data;
- PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
+ PDEBUG(D_V4L2, "Read exposure %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -259,7 +259,7 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val);
+ PDEBUG(D_V4L2, "Set exposure to %d", val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
goto out;
@@ -285,7 +285,7 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
*val = (data & S5K4AA_RM_V_FLIP) >> 7;
- PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+ PDEBUG(D_V4L2, "Read vertical flip %d", *val);
out:
return (err < 0) ? err : 0;
@@ -297,7 +297,7 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+ PDEBUG(D_V4L2, "Set vertical flip to %d", val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
goto out;
@@ -341,7 +341,7 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
*val = (data & S5K4AA_RM_H_FLIP) >> 6;
- PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+ PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -352,7 +352,7 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d",
+ PDEBUG(D_V4L2, "Set horizontal flip to %d",
val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
@@ -397,7 +397,7 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
*val = data;
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
out:
return (err < 0) ? err : 0;
@@ -409,7 +409,7 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set gain to %d", val);
+ PDEBUG(D_V4L2, "Set gain to %d", val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
goto out;
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 48abc6c8b..87167fb92 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -1,7 +1,7 @@
/*
* Driver for the s5k4aa sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -63,7 +63,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int s5k4aa_probe(struct sd *sd);
int s5k4aa_init(struct sd *sd);
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index b4b33c2d0..8988a728e 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -1,7 +1,7 @@
/*
* Driver for the s5k83a sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -101,7 +101,7 @@ int s5k83a_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len && !len; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
@@ -135,7 +135,7 @@ int s5k83a_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 833708eb5..ee3ee9cfc 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -1,7 +1,7 @@
/*
* Driver for the s5k83a sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -41,8 +41,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
-
int s5k83a_probe(struct sd *sd);
int s5k83a_init(struct sd *sd);
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_sensor.h b/linux/drivers/media/video/gspca/m5602/m5602_sensor.h
index 930fcaab4..60c9a48e0 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -1,7 +1,7 @@
/*
* USB Driver for ALi m5602 based webcams
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c
index b7457fc60..1c404e454 100644
--- a/linux/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c
@@ -600,13 +600,14 @@ retry:
since we may get here before the stream has been fully set-up */
if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
while (count >= itv->dma_data_req_size) {
- if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) {
- bytes_written += itv->dma_data_req_size;
- user_buf += itv->dma_data_req_size;
- count -= itv->dma_data_req_size;
- } else {
- break;
- }
+ rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);
+
+ if (rc < 0)
+ return rc;
+
+ bytes_written += itv->dma_data_req_size;
+ user_buf += itv->dma_data_req_size;
+ count -= itv->dma_data_req_size;
}
if (count == 0) {
IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index 8696527ab..208fb5484 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -509,7 +509,6 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct ivtv_open_id *id = fh;
- struct ivtv *itv = id->itv;
s32 w = fmt->fmt.pix.width;
s32 h = fmt->fmt.pix.height;
int field = fmt->fmt.pix.field;
@@ -517,7 +516,22 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
w = min(w, 720);
w = max(w, 2);
- h = min(h, itv->is_out_50hz ? 576 : 480);
+ /* Why can the height be 576 even when the output is NTSC?
+
+ Internally the buffers of the PVR350 are always set to 720x576. The
+ decoded video frame will always be placed in the top left corner of
+ this buffer. For any video which is not 720x576, the buffer will
+ then be cropped to remove the unused right and lower areas, with
+ the remaining image being scaled by the hardware to fit the display
+ area. The video can be scaled both up and down, so a 720x480 video
+ can be displayed full-screen on PAL and a 720x576 video can be
+ displayed without cropping on NTSC.
+
+ Note that the scaling only occurs on the video stream, the osd
+ resolution is locked to the broadcast standard and not scaled.
+
+ Thanks to Ian Armstrong for this explanation. */
+ h = min(h, 576);
h = max(h, 2);
if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
fmt->fmt.pix.field = field;
diff --git a/linux/drivers/media/video/ks0127.c b/linux/drivers/media/video/ks0127.c
index b21b6f097..16526165b 100644
--- a/linux/drivers/media/video/ks0127.c
+++ b/linux/drivers/media/video/ks0127.c
@@ -33,28 +33,21 @@
* V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard
*/
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include "ks0127.h"
-
#include <linux/i2c.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include "ks0127.h"
#include "compat.h"
-#define dprintk if (debug) printk
-
-/* i2c identification */
-#define I2C_KS0127_ADDON 0xD8
-#define I2C_KS0127_ONBOARD 0xDA
+MODULE_DESCRIPTION("KS0127 video decoder driver");
+MODULE_AUTHOR("Ryan Drake");
+MODULE_LICENSE("GPL");
#define KS_TYPE_UNKNOWN 0
#define KS_TYPE_0122S 1
@@ -205,8 +198,6 @@ struct adjust {
};
struct ks0127 {
- struct i2c_client *client;
- unsigned char addr;
int format_width;
int format_height;
int cap_width;
@@ -221,16 +212,18 @@ static int debug; /* insmod parameter */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug output");
-MODULE_LICENSE("GPL");
static u8 reg_defaults[64];
-
-
static void init_reg_defaults(void)
{
+ static int initialized;
u8 *table = reg_defaults;
+ if (initialized)
+ return;
+ initialized = 1;
+
table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */
table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */
table[KS_CMDC] = 0x00; /* Test options */
@@ -309,50 +302,53 @@ static void init_reg_defaults(void)
* An explanation from kayork@mail.utexas.edu:
*
* During I2C reads, the KS0127 only samples for a stop condition
- * during the place where the acknoledge bit should be. Any standard
+ * during the place where the acknowledge bit should be. Any standard
* I2C implementation (correctly) throws in another clock transition
* at the 9th bit, and the KS0127 will not recognize the stop condition
* and will continue to clock out data.
*
* So we have to do the read ourself. Big deal.
- workaround in i2c-algo-bit
+ * workaround in i2c-algo-bit
*/
-static u8 ks0127_read(struct ks0127 *ks, u8 reg)
+static u8 ks0127_read(struct i2c_client *c, u8 reg)
{
- struct i2c_client *c = ks->client;
char val = 0;
struct i2c_msg msgs[] = {
- {c->addr, 0, sizeof(reg), &reg},
- {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}};
+ { c->addr, 0, sizeof(reg), &reg },
+ { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+ };
int ret;
ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
- dprintk("ks0127_write error\n");
+ v4l_dbg(1, debug, c, "read error\n");
return val;
}
-static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val)
+static void ks0127_write(struct i2c_client *c, u8 reg, u8 val)
{
- char msg[] = {reg, val};
+ struct ks0127 *ks = i2c_get_clientdata(c);
+ char msg[] = { reg, val };
- if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg))
- dprintk("ks0127_write error\n");
+ if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg))
+ v4l_dbg(1, debug, c, "write error\n");
ks->regs[reg] = val;
}
/* generic bit-twiddling */
-static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
+static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
{
+ struct ks0127 *ks = i2c_get_clientdata(client);
+
u8 val = ks->regs[reg];
val = (val & and_v) | or_v;
- ks0127_write(ks, reg, val);
+ ks0127_write(client, reg, val);
}
@@ -360,73 +356,69 @@ static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
/****************************************************************************
* ks0127 private api
****************************************************************************/
-static void ks0127_reset(struct ks0127* ks)
+static void ks0127_reset(struct i2c_client *c)
{
- int i;
+ struct ks0127 *ks = i2c_get_clientdata(c);
u8 *table = reg_defaults;
+ int i;
ks->ks_type = KS_TYPE_UNKNOWN;
- dprintk("ks0127: reset\n");
+ v4l_dbg(1, debug, c, "reset\n");
msleep(1);
/* initialize all registers to known values */
/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
- for(i = 1; i < 33; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 1; i < 33; i++)
+ ks0127_write(c, i, table[i]);
- for(i = 35; i < 40; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 35; i < 40; i++)
+ ks0127_write(c, i, table[i]);
- for(i = 41; i < 56; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 41; i < 56; i++)
+ ks0127_write(c, i, table[i]);
- for(i = 58; i < 64; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 58; i < 64; i++)
+ ks0127_write(c, i, table[i]);
- if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) {
+ if ((ks0127_read(c, KS_STAT) & 0x80) == 0) {
ks->ks_type = KS_TYPE_0122S;
- dprintk("ks0127: ks0122s Found\n");
+ v4l_dbg(1, debug, c, "ks0122s found\n");
return;
}
- switch(ks0127_read(ks, KS_CMDE) & 0x0f) {
-
+ switch (ks0127_read(c, KS_CMDE) & 0x0f) {
case 0:
ks->ks_type = KS_TYPE_0127;
- dprintk("ks0127: ks0127 found\n");
+ v4l_dbg(1, debug, c, "ks0127 found\n");
break;
case 9:
ks->ks_type = KS_TYPE_0127B;
- dprintk("ks0127: ks0127B Revision A found\n");
+ v4l_dbg(1, debug, c, "ks0127B Revision A found\n");
break;
default:
- dprintk("ks0127: unknown revision\n");
+ v4l_dbg(1, debug, c, "unknown revision\n");
break;
}
}
-static int ks0127_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
+static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
{
- struct ks0127 *ks = i2c_get_clientdata(client);
-
- int *iarg = (int*)arg;
-
+ struct ks0127 *ks = i2c_get_clientdata(c);
+ int *iarg = (int *)arg;
int status;
if (!ks)
return -ENODEV;
switch (cmd) {
-
case DECODER_INIT:
- dprintk("ks0127: command DECODER_INIT\n");
- ks0127_reset(ks);
+ v4l_dbg(1, debug, c, "DECODER_INIT\n");
+ ks0127_reset(c);
break;
case DECODER_SET_INPUT:
@@ -437,161 +429,160 @@ static int ks0127_command(struct i2c_client *client,
case KS_INPUT_COMPOSITE_4:
case KS_INPUT_COMPOSITE_5:
case KS_INPUT_COMPOSITE_6:
- dprintk("ks0127: command DECODER_SET_INPUT %d: "
- "Composite\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT %d: Composite\n", *iarg);
/* autodetect 50/60 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
- ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
+ ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
/* set input line */
- ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
+ ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
/* non-freerunning mode */
- ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
+ ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
/* analog input */
- ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
+ ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
/* enable chroma demodulation */
- ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
+ ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
/* chroma trap, HYBWR=1 */
- ks0127_and_or(ks, KS_LUMA, 0x00,
+ ks0127_and_or(c, KS_LUMA, 0x00,
(reg_defaults[KS_LUMA])|0x0c);
/* scaler fullbw, luma comb off */
- ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+ ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
/* manual chroma comb .25 .5 .25 */
- ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90);
+ ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90);
/* chroma path delay */
- ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90);
+ ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90);
- ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+ ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
break;
case KS_INPUT_SVIDEO_1:
case KS_INPUT_SVIDEO_2:
case KS_INPUT_SVIDEO_3:
- dprintk("ks0127: command DECODER_SET_INPUT %d: "
- "S-Video\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT %d: S-Video\n", *iarg);
/* autodetect 50/60 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
- ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
+ ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
/* set input line */
- ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
+ ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
/* non-freerunning mode */
- ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
+ ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
/* analog input */
- ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
+ ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
/* enable chroma demodulation */
- ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
- ks0127_and_or(ks, KS_LUMA, 0x00,
+ ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
+ ks0127_and_or(c, KS_LUMA, 0x00,
reg_defaults[KS_LUMA]);
/* disable luma comb */
- ks0127_and_or(ks, KS_VERTIA, 0x08,
+ ks0127_and_or(c, KS_VERTIA, 0x08,
(reg_defaults[KS_VERTIA]&0xf0)|0x01);
- ks0127_and_or(ks, KS_VERTIC, 0x0f,
+ ks0127_and_or(c, KS_VERTIC, 0x0f,
reg_defaults[KS_VERTIC]&0xf0);
- ks0127_and_or(ks, KS_CHROMB, 0x0f,
+ ks0127_and_or(c, KS_CHROMB, 0x0f,
reg_defaults[KS_CHROMB]&0xf0);
- ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+ ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
break;
case KS_INPUT_YUV656:
- dprintk("ks0127: command DECODER_SET_INPUT 15: "
- "YUV656\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT 15: YUV656\n");
if (ks->norm == VIDEO_MODE_NTSC ||
ks->norm == KS_STD_PAL_M)
/* force 60 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x03);
else
/* force 50 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x02);
- ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */
+ ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */
/* set input line and VALIGN */
- ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40));
+ ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40));
/* freerunning mode, */
/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
- ks0127_and_or(ks, KS_CMDC, 0x70, 0x87);
+ ks0127_and_or(c, KS_CMDC, 0x70, 0x87);
/* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
- ks0127_and_or(ks, KS_CMDD, 0x03, 0x08);
+ ks0127_and_or(c, KS_CMDD, 0x03, 0x08);
/* disable chroma demodulation */
- ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30);
+ ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30);
/* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
- ks0127_and_or(ks, KS_LUMA, 0x00, 0x71);
- ks0127_and_or(ks, KS_VERTIC, 0x0f,
+ ks0127_and_or(c, KS_LUMA, 0x00, 0x71);
+ ks0127_and_or(c, KS_VERTIC, 0x0f,
reg_defaults[KS_VERTIC]&0xf0);
/* scaler fullbw, luma comb off */
- ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+ ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
- ks0127_and_or(ks, KS_CHROMB, 0x0f,
+ ks0127_and_or(c, KS_CHROMB, 0x0f,
reg_defaults[KS_CHROMB]&0xf0);
- ks0127_and_or(ks, KS_CON, 0x00, 0x00);
- ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */
+ ks0127_and_or(c, KS_CON, 0x00, 0x00);
+ ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */
/* spec: 229 (e5) */
- ks0127_and_or(ks, KS_SAT, 0x00, 0xe8);
- ks0127_and_or(ks, KS_HUE, 0x00, 0);
+ ks0127_and_or(c, KS_SAT, 0x00, 0xe8);
+ ks0127_and_or(c, KS_HUE, 0x00, 0);
- ks0127_and_or(ks, KS_UGAIN, 0x00, 238);
- ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00);
+ ks0127_and_or(c, KS_UGAIN, 0x00, 238);
+ ks0127_and_or(c, KS_VGAIN, 0x00, 0x00);
/*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
- ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f);
- ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00);
+ ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f);
+ ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00);
break;
default:
- dprintk("ks0127: command DECODER_SET_INPUT: "
- "Unknown input %d\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT: Unknown input %d\n", *iarg);
break;
}
/* hack: CDMLPF sometimes spontaneously switches on; */
/* force back off */
- ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]);
+ ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
break;
case DECODER_SET_OUTPUT:
switch(*iarg) {
case KS_OUTPUT_YUV656E:
- dprintk("ks0127: command DECODER_SET_OUTPUT: "
- "OUTPUT_YUV656E (Missing)\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
return -EINVAL;
- break;
case KS_OUTPUT_EXV:
- dprintk("ks0127: command DECODER_SET_OUTPUT: "
- "OUTPUT_EXV\n");
- ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_OUTPUT: OUTPUT_EXV\n");
+ ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
break;
}
break;
- case DECODER_SET_NORM: //sam This block mixes old and new norm names...
+ case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
/* Set to automatic SECAM/Fsc mode */
- ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
ks->norm = *iarg;
- switch(*iarg)
- {
+ switch (*iarg) {
/* this is untested !! */
/* It just detects PAL_N/NTSC_M (no special frequencies) */
/* And you have to set the standard a second time afterwards */
case VIDEO_MODE_AUTO:
- dprintk("ks0127: command DECODER_SET_NORM: AUTO\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: AUTO\n");
/* The chip determines the format */
/* based on the current field rate */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
/* This is wrong for PAL ! As I said, */
/* you need to set the standard once again !! */
ks->format_height = 240;
@@ -599,84 +590,86 @@ static int ks0127_command(struct i2c_client *client,
break;
case VIDEO_MODE_NTSC:
- dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: NTSC_M\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
ks->format_height = 240;
ks->format_width = 704;
break;
case KS_STD_NTSC_N:
- dprintk("ks0127: command KS0127_SET_STANDARD: "
- "NTSC_N (fixme)\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+ v4l_dbg(1, debug, c,
+ "KS0127_SET_NORM: NTSC_N (fixme)\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
ks->format_height = 240;
ks->format_width = 704;
break;
case VIDEO_MODE_PAL:
- dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: PAL_N\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
ks->format_height = 290;
ks->format_width = 704;
break;
case KS_STD_PAL_M:
- dprintk("ks0127: command KS0127_SET_STANDARD: "
- "PAL_M (fixme)\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+ v4l_dbg(1, debug, c,
+ "KS0127_SET_NORM: PAL_M (fixme)\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
ks->format_height = 290;
ks->format_width = 704;
break;
case VIDEO_MODE_SECAM:
- dprintk("ks0127: command KS0127_SET_STANDARD: "
- "SECAM\n");
+ v4l_dbg(1, debug, c,
+ "KS0127_SET_NORM: SECAM\n");
ks->format_height = 290;
ks->format_width = 704;
/* set to secam autodetection */
- ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20);
- ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+ ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20);
+ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
schedule_timeout_interruptible(HZ/10+1);
/* did it autodetect? */
- if (ks0127_read(ks, KS_DEMOD) & 0x40)
+ if (ks0127_read(c, KS_DEMOD) & 0x40)
break;
/* force to secam mode */
- ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f);
+ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
break;
default:
- dprintk("ks0127: command DECODER_SET_NORM: "
- "Unknown norm %d\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: Unknown norm %d\n", *iarg);
break;
}
break;
case DECODER_SET_PICTURE:
- dprintk("ks0127: command DECODER_SET_PICTURE "
- "not yet supported (fixme)\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_PICTURE: not yet supported\n");
return -EINVAL;
- //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE
- //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE
- //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE?
- //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE
- //sam todo: KS0127_SET_AGC_MODE:
- //sam todo: KS0127_SET_AGC:
- //sam todo: KS0127_SET_CHROMA_MODE:
- //sam todo: KS0127_SET_PIXCLK_MODE:
- //sam todo: KS0127_SET_GAMMA_MODE:
- //sam todo: KS0127_SET_UGAIN:
- //sam todo: KS0127_SET_VGAIN:
- //sam todo: KS0127_SET_INVALY:
- //sam todo: KS0127_SET_INVALU:
- //sam todo: KS0127_SET_INVALV:
- //sam todo: KS0127_SET_UNUSEY:
- //sam todo: KS0127_SET_UNUSEU:
- //sam todo: KS0127_SET_UNUSEV:
- //sam todo: KS0127_SET_VSALIGN_MODE:
+ /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
+ /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
+ /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
+ /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
+ /* sam todo: KS0127_SET_AGC_MODE: */
+ /* sam todo: KS0127_SET_AGC: */
+ /* sam todo: KS0127_SET_CHROMA_MODE: */
+ /* sam todo: KS0127_SET_PIXCLK_MODE: */
+ /* sam todo: KS0127_SET_GAMMA_MODE: */
+ /* sam todo: KS0127_SET_UGAIN: */
+ /* sam todo: KS0127_SET_VGAIN: */
+ /* sam todo: KS0127_SET_INVALY: */
+ /* sam todo: KS0127_SET_INVALU: */
+ /* sam todo: KS0127_SET_INVALV: */
+ /* sam todo: KS0127_SET_UNUSEY: */
+ /* sam todo: KS0127_SET_UNUSEU: */
+ /* sam todo: KS0127_SET_UNUSEV: */
+ /* sam todo: KS0127_SET_VSALIGN_MODE: */
case DECODER_ENABLE_OUTPUT:
{
@@ -685,34 +678,32 @@ static int ks0127_command(struct i2c_client *client,
iarg = arg;
enable = (*iarg != 0);
if (enable) {
- dprintk("ks0127: command "
- "DECODER_ENABLE_OUTPUT on "
- "(%d)\n", enable);
+ v4l_dbg(1, debug, c,
+ "DECODER_ENABLE_OUTPUT on\n");
/* All output pins on */
- ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
+ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
/* Obey the OEN pin */
- ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
+ ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
} else {
- dprintk("ks0127: command "
- "DECODER_ENABLE_OUTPUT off "
- "(%d)\n", enable);
+ v4l_dbg(1, debug, c,
+ "DECODER_ENABLE_OUTPUT off\n");
/* Video output pins off */
- ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
+ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
/* Ignore the OEN pin */
- ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
+ ks0127_and_or(c, KS_CDEM, 0x7f, 0x80);
}
- }
break;
+ }
- //sam todo: KS0127_SET_OUTPUT_MODE:
- //sam todo: KS0127_SET_WIDTH:
- //sam todo: KS0127_SET_HEIGHT:
- //sam todo: KS0127_SET_HSCALE:
+ /* sam todo: KS0127_SET_OUTPUT_MODE: */
+ /* sam todo: KS0127_SET_WIDTH: */
+ /* sam todo: KS0127_SET_HEIGHT: */
+ /* sam todo: KS0127_SET_HSCALE: */
case DECODER_GET_STATUS:
- dprintk("ks0127: command DECODER_GET_STATUS\n");
+ v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
*iarg = 0;
- status = ks0127_read(ks, KS_STAT);
+ status = ks0127_read(c, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
*iarg = (*iarg | DECODER_STATUS_GOOD);
if ((status & 0x01)) /* CLOCK set */
@@ -723,124 +714,85 @@ static int ks0127_command(struct i2c_client *client,
*iarg = (*iarg | DECODER_STATUS_NTSC);
break;
- //Catch any unknown command
+ /* Catch any unknown command */
default:
- dprintk("ks0127: command unknown: %04X\n", cmd);
+ v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd);
return -EINVAL;
}
return 0;
}
-
-
-static int ks0127_probe(struct i2c_adapter *adapter);
-static int ks0127_detach(struct i2c_client *client);
-static int ks0127_command(struct i2c_client *client,
- unsigned int cmd, void *arg);
-
-
-
/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
- I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};
-static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-static struct i2c_client_address_data addr_data = {
- normal_i2c,
- probe,
- ignore,
-};
+#define I2C_KS0127_ADDON 0xD8
+#define I2C_KS0127_ONBOARD 0xDA
-static struct i2c_driver i2c_driver_ks0127 = {
- .driver.name = "ks0127",
- .id = I2C_DRIVERID_KS0127,
- .attach_adapter = ks0127_probe,
- .detach_client = ks0127_detach,
- .command = ks0127_command
+static unsigned short normal_i2c[] = {
+ I2C_KS0127_ADDON >> 1,
+ I2C_KS0127_ONBOARD >> 1,
+ I2C_CLIENT_END
};
-static struct i2c_client ks0127_client_tmpl =
-{
- .name = "(ks0127 unset)",
- .addr = 0,
- .adapter = NULL,
- .driver = &i2c_driver_ks0127,
-};
+I2C_CLIENT_INSMOD;
-static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
+static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id)
{
struct ks0127 *ks;
- struct i2c_client *client;
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL)
- return -ENOMEM;
- memcpy(client, &ks0127_client_tmpl, sizeof(*client));
+ v4l_info(c, "%s chip found @ 0x%x (%s)\n",
+ c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+ c->addr << 1, c->adapter->name);
ks = kzalloc(sizeof(*ks), GFP_KERNEL);
- if (ks == NULL) {
- kfree(client);
+ if (ks == NULL)
return -ENOMEM;
- }
- i2c_set_clientdata(client, ks);
- client->adapter = adapter;
- client->addr = addr;
- sprintf(client->name, "ks0127-%02x", adapter->id);
+ i2c_set_clientdata(c, ks);
- ks->client = client;
- ks->addr = addr;
ks->ks_type = KS_TYPE_UNKNOWN;
/* power up */
- ks0127_write(ks, KS_CMDA, 0x2c);
+ init_reg_defaults();
+ ks0127_write(c, KS_CMDA, 0x2c);
mdelay(10);
/* reset the device */
- ks0127_reset(ks);
- printk(KERN_INFO "ks0127: attach: %s video decoder\n",
- ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
-
- i2c_attach_client(client);
- return 0;
-}
-
-
-static int ks0127_probe(struct i2c_adapter *adapter)
-{
- if (adapter->id == I2C_HW_B_ZR36067)
- return i2c_probe(adapter, &addr_data, ks0127_found_proc);
+ ks0127_reset(c);
return 0;
}
-static int ks0127_detach(struct i2c_client *client)
+static int ks0127_remove(struct i2c_client *c)
{
- struct ks0127 *ks = i2c_get_clientdata(client);
+ struct ks0127 *ks = i2c_get_clientdata(c);
- ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
- ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
+ ks0127_write(c, KS_OFMTA, 0x20); /* tristate */
+ ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */
- i2c_detach_client(client);
kfree(ks);
- kfree(client);
-
- dprintk("ks0127: detach\n");
return 0;
}
-
-static int __devinit ks0127_init_module(void)
-{
- init_reg_defaults();
- return i2c_add_driver(&i2c_driver_ks0127);
-}
-
-static void __devexit ks0127_cleanup_module(void)
+static int ks0127_legacy_probe(struct i2c_adapter *adapter)
{
- i2c_del_driver(&i2c_driver_ks0127);
+ return adapter->id == I2C_HW_B_ZR36067;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id ks0127_id[] = {
+ { "ks0127", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ks0127_id);
+#endif
-module_init(ks0127_init_module);
-module_exit(ks0127_cleanup_module);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "ks0127",
+ .driverid = I2C_DRIVERID_KS0127,
+ .command = ks0127_command,
+ .probe = ks0127_probe,
+ .remove = ks0127_remove,
+ .legacy_probe = ks0127_legacy_probe,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = ks0127_id,
+#endif
+};
diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c
index 0692e4bef..15eb8bd7a 100644
--- a/linux/drivers/media/video/saa7110.c
+++ b/linux/drivers/media/video/saa7110.c
@@ -31,37 +31,25 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/wait.h>
-#include <asm/io.h>
#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include "compat.h"
MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
MODULE_AUTHOR("Pauline Middelink");
MODULE_LICENSE("GPL");
-#include <linux/i2c.h>
-
-#define I2C_NAME(s) (s)->name
-
-#include "compat.h"
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <linux/video_decoder.h>
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */
#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */
-#define I2C_SAA7110 0x9C /* or 0x9E */
-
#define SAA7110_NR_REG 0x35
struct saa7110 {
@@ -82,10 +70,7 @@ struct saa7110 {
/* I2C support functions */
/* ----------------------------------------------------------------------- */
-static int
-saa7110_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static int saa7110_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7110 *decoder = i2c_get_clientdata(client);
@@ -93,10 +78,7 @@ saa7110_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int
-saa7110_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg = *data; /* first register to write to */
@@ -116,8 +98,8 @@ saa7110_write_block (struct i2c_client *client,
memcpy(decoder->reg + reg, data + 1, len - 1);
} else {
for (++data, --len; len; len--) {
- if ((ret = saa7110_write(client, reg++,
- *data++)) < 0)
+ ret = saa7110_write(client, reg++, *data++);
+ if (ret < 0)
break;
}
}
@@ -125,8 +107,7 @@ saa7110_write_block (struct i2c_client *client,
return ret;
}
-static inline int
-saa7110_read (struct i2c_client *client)
+static inline int saa7110_read(struct i2c_client *client)
{
return i2c_smbus_read_byte(client);
}
@@ -139,9 +120,7 @@ saa7110_read (struct i2c_client *client)
#define FRESP_06H_SVIDEO 0x83 //0xC0
-static int
-saa7110_selmux (struct i2c_client *client,
- int chan)
+static int saa7110_selmux(struct i2c_client *client, int chan)
{
static const unsigned char modes[9][8] = {
/* mode 0 */
@@ -198,8 +177,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = {
/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
};
-static int
-determine_norm (struct i2c_client *client)
+static int determine_norm(struct i2c_client *client)
{
DEFINE_WAIT(wait);
struct saa7110 *decoder = i2c_get_clientdata(client);
@@ -213,29 +191,23 @@ determine_norm (struct i2c_client *client)
finish_wait(&decoder->wq, &wait);
status = saa7110_read(client);
if (status & 0x40) {
- dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status);
return decoder->norm; // no change
}
if ((status & 3) == 0) {
saa7110_write(client, 0x06, 0x83);
if (status & 0x20) {
- dprintk(1,
- KERN_INFO
- "%s: status=0x%02x (NTSC/no color)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
//saa7110_write(client,0x2E,0x81);
return VIDEO_MODE_NTSC;
}
- dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
//saa7110_write(client,0x2E,0x9A);
return VIDEO_MODE_PAL;
}
//saa7110_write(client,0x06,0x03);
if (status & 0x20) { /* 60Hz */
- dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status);
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x50);
saa7110_write(client, 0x11, 0x2C);
@@ -255,13 +227,11 @@ determine_norm (struct i2c_client *client)
status = saa7110_read(client);
if ((status & 0x03) == 0x01) {
- dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
saa7110_write(client, 0x0D, 0x87);
return VIDEO_MODE_SECAM;
}
- dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
return VIDEO_MODE_PAL;
}
@@ -287,8 +257,8 @@ saa7110_command (struct i2c_client *client,
VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
dc->inputs = SAA7110_MAX_INPUT;
dc->outputs = SAA7110_MAX_OUTPUT;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -296,8 +266,8 @@ saa7110_command (struct i2c_client *client,
int res = 0;
status = saa7110_read(client);
- dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n",
- I2C_NAME(client), status, decoder->norm);
+ v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
+ status, decoder->norm);
if (!(status & 0x40))
res |= DECODER_STATUS_GOOD;
if (status & 0x03)
@@ -315,8 +285,8 @@ saa7110_command (struct i2c_client *client,
break;
}
*(int *) arg = res;
- }
break;
+ }
case DECODER_SET_NORM:
v = *(int *) arg;
@@ -329,34 +299,24 @@ saa7110_command (struct i2c_client *client,
saa7110_write(client, 0x0F, 0x50);
saa7110_write(client, 0x11, 0x2C);
//saa7110_write(client, 0x2E, 0x81);
- dprintk(1,
- KERN_INFO "%s: switched to NTSC\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to NTSC\n");
break;
case VIDEO_MODE_PAL:
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
//saa7110_write(client, 0x2E, 0x9A);
- dprintk(1,
- KERN_INFO "%s: switched to PAL\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to PAL\n");
break;
case VIDEO_MODE_SECAM:
saa7110_write(client, 0x0D, 0x87);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
//saa7110_write(client, 0x2E, 0x9A);
- dprintk(1,
- KERN_INFO
- "%s: switched to SECAM\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to SECAM\n");
break;
case VIDEO_MODE_AUTO:
- dprintk(1,
- KERN_INFO
- "%s: TV standard detection...\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to AUTO\n");
decoder->norm = determine_norm(client);
*(int *) arg = decoder->norm;
break;
@@ -369,15 +329,12 @@ saa7110_command (struct i2c_client *client,
case DECODER_SET_INPUT:
v = *(int *) arg;
if (v < 0 || v > SAA7110_MAX_INPUT) {
- dprintk(1,
- KERN_INFO "%s: input=%d not available\n",
- I2C_NAME(client), v);
+ v4l_dbg(1, debug, client, "input=%d not available\n", v);
return -EINVAL;
}
if (decoder->input != v) {
saa7110_selmux(client, v);
- dprintk(1, KERN_INFO "%s: switched to input=%d\n",
- I2C_NAME(client), v);
+ v4l_dbg(1, debug, client, "switched to input=%d\n", v);
}
break;
@@ -393,8 +350,7 @@ saa7110_command (struct i2c_client *client,
if (decoder->enable != v) {
decoder->enable = v;
saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
- dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client),
- v ? "on" : "off");
+ v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off");
}
break;
@@ -424,23 +380,23 @@ saa7110_command (struct i2c_client *client,
saa7110_write(client, 0x07,
(decoder->hue >> 8) - 128);
}
- }
break;
+ }
case DECODER_DUMP:
+ if (!debug)
+ break;
for (v = 0; v < SAA7110_NR_REG; v += 16) {
int j;
- dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client),
- v);
+ v4l_dbg(1, debug, client, "%02x:", v);
for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
- dprintk(1, " %02x", decoder->reg[v + j]);
- dprintk(1, "\n");
+ printk(KERN_CONT " %02x", decoder->reg[v + j]);
+ printk(KERN_CONT "\n");
}
break;
default:
- dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n",
- cmd);
+ v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
return -EINVAL;
}
return 0;
@@ -452,55 +408,28 @@ saa7110_command (struct i2c_client *client,
* Generic i2c probe
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static unsigned short normal_i2c[] = {
- I2C_SAA7110 >> 1,
- (I2C_SAA7110 >> 1) + 1,
- I2C_CLIENT_END
-};
-static unsigned short ignore = I2C_CLIENT_END;
+static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+I2C_CLIENT_INSMOD;
-static struct i2c_driver i2c_driver_saa7110;
-
-static int
-saa7110_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7110_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client;
struct saa7110 *decoder;
int rv;
- dprintk(1,
- KERN_INFO
- "saa7110.c: detecting saa7110 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality
- (adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7110;
- strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
- if (!decoder) {
- kfree(client);
+ if (!decoder)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_PAL;
decoder->input = 0;
decoder->enable = 1;
@@ -511,18 +440,10 @@ saa7110_detect_client (struct i2c_adapter *adapter,
init_waitqueue_head(&decoder->wq);
i2c_set_clientdata(client, decoder);
- rv = i2c_attach_client(client);
- if (rv) {
- kfree(client);
- kfree(decoder);
- return rv;
- }
-
rv = saa7110_write_block(client, initseq, sizeof(initseq));
- if (rv < 0)
- dprintk(1, KERN_ERR "%s_attach: init status %d\n",
- I2C_NAME(client), rv);
- else {
+ if (rv < 0) {
+ v4l_dbg(1, debug, client, "init status %d\n", rv);
+ } else {
int ver, status;
saa7110_write(client, 0x21, 0x10);
saa7110_write(client, 0x0e, 0x18);
@@ -531,10 +452,8 @@ saa7110_detect_client (struct i2c_adapter *adapter,
saa7110_write(client, 0x0D, 0x06);
//mdelay(150);
status = saa7110_read(client);
- dprintk(1,
- KERN_INFO
- "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n",
- I2C_NAME(client), ver, client->addr << 1, status);
+ v4l_dbg(1, debug, client, "version %x, status=0x%02x\n",
+ ver, status);
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
@@ -548,58 +467,29 @@ saa7110_detect_client (struct i2c_adapter *adapter,
return 0;
}
-static int
-saa7110_attach_adapter (struct i2c_adapter *adapter)
+static int saa7110_remove(struct i2c_client *client)
{
- dprintk(1,
- KERN_INFO
- "saa7110.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
-}
-
-static int
-saa7110_detach_client (struct i2c_client *client)
-{
- struct saa7110 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7110 = {
- .driver = {
- .name = "saa7110",
- },
-
- .id = I2C_DRIVERID_SAA7110,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id saa7110_id[] = {
+ { "saa7110", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7110_id);
- .attach_adapter = saa7110_attach_adapter,
- .detach_client = saa7110_detach_client,
+#endif
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7110",
+ .driverid = I2C_DRIVERID_SAA7110,
.command = saa7110_command,
+ .probe = saa7110_probe,
+ .remove = saa7110_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = saa7110_id,
+#endif
};
-
-static int __init
-saa7110_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7110);
-}
-
-static void __exit
-saa7110_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7110);
-}
-
-module_init(saa7110_init);
-module_exit(saa7110_exit);
diff --git a/linux/drivers/media/video/saa7111.c b/linux/drivers/media/video/saa7111.c
index 917fb2553..94e5d0b4e 100644
--- a/linux/drivers/media/video/saa7111.c
+++ b/linux/drivers/media/video/saa7111.c
@@ -28,44 +28,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
#include "compat.h"
MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
#define SAA7111_NR_REG 0x18
@@ -78,14 +59,9 @@ struct saa7111 {
int enable;
};
-#define I2C_SAA7111 0x48
-
/* ----------------------------------------------------------------------- */
-static inline int
-saa7111_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
@@ -93,8 +69,7 @@ saa7111_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline void
-saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
@@ -104,10 +79,7 @@ saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
}
}
-static int
-saa7111_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -128,18 +100,17 @@ saa7111_write_block (struct i2c_client *client,
decoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = saa7111_write(client, reg,
- *data++)) < 0)
+ ret = saa7111_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -148,16 +119,13 @@ saa7111_write_block (struct i2c_client *client,
return ret;
}
-static int
-saa7111_init_decoder (struct i2c_client *client,
- struct video_decoder_init *init)
+static int saa7111_init_decoder(struct i2c_client *client,
+ struct video_decoder_init *init)
{
return saa7111_write_block(client, init->data, init->len);
}
-static inline int
-saa7111_read (struct i2c_client *client,
- u8 reg)
+static inline int saa7111_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
@@ -204,28 +172,23 @@ static const unsigned char saa7111_i2c_init[] = {
0x17, 0x00, /* 17 - VBI */
};
-static int
-saa7111_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
break;
case DECODER_INIT:
{
struct video_decoder_init *init = arg;
+ struct video_decoder_init vdi;
+
if (NULL != init)
return saa7111_init_decoder(client, init);
- else {
- struct video_decoder_init vdi;
- vdi.data = saa7111_i2c_init;
- vdi.len = sizeof(saa7111_i2c_init);
- return saa7111_init_decoder(client, &vdi);
- }
+ vdi.data = saa7111_i2c_init;
+ vdi.len = sizeof(saa7111_i2c_init);
+ return saa7111_init_decoder(client, &vdi);
}
case DECODER_DUMP:
@@ -235,15 +198,15 @@ saa7111_command (struct i2c_client *client,
for (i = 0; i < SAA7111_NR_REG; i += 16) {
int j;
- printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+ v4l_info(client, "%03x", i);
for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
- printk(" %02x",
+ printk(KERN_CONT " %02x",
saa7111_read(client, i + j));
}
- printk("\n");
+ printk(KERN_CONT "\n");
}
- }
break;
+ }
case DECODER_GET_CAPABILITIES:
{
@@ -256,8 +219,8 @@ saa7111_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -266,8 +229,7 @@ saa7111_command (struct i2c_client *client,
int res;
status = saa7111_read(client, 0x1f);
- dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
res = 0;
if ((status & (1 << 6)) == 0) {
res |= DECODER_STATUS_GOOD;
@@ -295,8 +257,8 @@ saa7111_command (struct i2c_client *client,
res |= DECODER_STATUS_COLOR;
}
*iarg = res;
- }
break;
+ }
case DECODER_SET_GPIO:
{
@@ -363,8 +325,8 @@ saa7111_command (struct i2c_client *client,
}
decoder->norm = *iarg;
- }
break;
+ }
case DECODER_SET_INPUT:
{
@@ -388,8 +350,8 @@ saa7111_command (struct i2c_client *client,
3) ? 0x80 :
0));
}
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
@@ -399,8 +361,8 @@ saa7111_command (struct i2c_client *client,
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
@@ -440,8 +402,8 @@ saa7111_command (struct i2c_client *client,
(decoder->reg[0x11] & 0xf3));
}
}
- }
break;
+ }
case DECODER_SET_PICTURE:
{
@@ -455,8 +417,8 @@ saa7111_command (struct i2c_client *client,
saa7111_write(client, 0x0c, pic->colour >> 9);
/* We want -128 to 127 we get 0-65535 */
saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
- }
break;
+ }
default:
return -EINVAL;
@@ -467,48 +429,23 @@ saa7111_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_saa7111;
+I2C_CLIENT_INSMOD;
-static int
-saa7111_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7111_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
- struct i2c_client *client;
struct saa7111 *decoder;
struct video_decoder_init vdi;
- dprintk(1,
- KERN_INFO
- "saa7111.c: detecting saa7111 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7111;
- strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
if (decoder == NULL) {
@@ -520,82 +457,41 @@ saa7111_detect_client (struct i2c_adapter *adapter,
decoder->enable = 1;
i2c_set_clientdata(client, decoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
vdi.data = saa7111_i2c_init;
vdi.len = sizeof(saa7111_i2c_init);
i = saa7111_init_decoder(client, &vdi);
if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
- I2C_NAME(client), i);
+ v4l_dbg(1, debug, client, "init status %d\n", i);
} else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x at address 0x%x\n",
- I2C_NAME(client), saa7111_read(client, 0x00) >> 4,
- client->addr << 1);
+ v4l_dbg(1, debug, client, "revision %x\n",
+ saa7111_read(client, 0x00) >> 4);
}
-
return 0;
}
-static int
-saa7111_attach_adapter (struct i2c_adapter *adapter)
+static int saa7111_remove(struct i2c_client *client)
{
- dprintk(1,
- KERN_INFO
- "saa7111.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7111_detect_client);
-}
-
-static int
-saa7111_detach_client (struct i2c_client *client)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7111 = {
- .driver = {
- .name = "saa7111",
- },
-
- .id = I2C_DRIVERID_SAA7111A,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id saa7111_id[] = {
+ { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7111_id);
- .attach_adapter = saa7111_attach_adapter,
- .detach_client = saa7111_detach_client,
+#endif
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7111",
+ .driverid = I2C_DRIVERID_SAA7111A,
.command = saa7111_command,
+ .probe = saa7111_probe,
+ .remove = saa7111_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = saa7111_id,
+#endif
};
-
-static int __init
-saa7111_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7111);
-}
-
-static void __exit
-saa7111_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7111);
-}
-
-module_init(saa7111_init);
-module_exit(saa7111_exit);
diff --git a/linux/drivers/media/video/saa7114.c b/linux/drivers/media/video/saa7114.c
index 158bd123c..6d380e255 100644
--- a/linux/drivers/media/video/saa7114.c
+++ b/linux/drivers/media/video/saa7114.c
@@ -29,44 +29,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
#include "compat.h"
MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(x) (x)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct saa7114 {
@@ -82,9 +63,6 @@ struct saa7114 {
int playback;
};
-#define I2C_SAA7114 0x42
-#define I2C_SAA7114A 0x40
-
#define I2C_DELAY 10
@@ -130,18 +108,12 @@ struct saa7114 {
/* ----------------------------------------------------------------------- */
-static inline int
-saa7114_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int
-saa7114_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -161,18 +133,17 @@ saa7114_write_block (struct i2c_client *client,
reg++;
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = saa7114_write(client, reg,
- *data++)) < 0)
+ ret = saa7114_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -181,9 +152,7 @@ saa7114_write_block (struct i2c_client *client,
return ret;
}
-static inline int
-saa7114_read (struct i2c_client *client,
- u8 reg)
+static inline int saa7114_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
@@ -453,15 +422,11 @@ static const unsigned char init[] = {
0xef, 0x00
};
-static int
-saa7114_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7114 *decoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
//dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
//saa7114_write_block(client, init, sizeof(init));
@@ -471,27 +436,28 @@ saa7114_command (struct i2c_client *client,
{
int i;
- dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
+ if (!debug)
+ break;
+ v4l_info(client, "decoder dump\n");
for (i = 0; i < 32; i += 16) {
int j;
- printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+ v4l_info(client, "%03x", i);
for (j = 0; j < 16; ++j) {
- printk(" %02x",
+ printk(KERN_CONT " %02x",
saa7114_read(client, i + j));
}
- printk("\n");
+ printk(KERN_CONT "\n");
}
- }
break;
+ }
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
- dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "get capabilities\n");
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
@@ -499,8 +465,8 @@ saa7114_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -510,8 +476,7 @@ saa7114_command (struct i2c_client *client,
status = saa7114_read(client, 0x1f);
- dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
res = 0;
if ((status & (1 << 6)) == 0) {
res |= DECODER_STATUS_GOOD;
@@ -539,8 +504,8 @@ saa7114_command (struct i2c_client *client,
res |= DECODER_STATUS_COLOR;
}
*iarg = res;
- }
break;
+ }
case DECODER_SET_NORM:
{
@@ -548,12 +513,11 @@ saa7114_command (struct i2c_client *client,
short int hoff = 0, voff = 0, w = 0, h = 0;
- dprintk(1, KERN_DEBUG "%s: decoder set norm ",
- I2C_NAME(client));
- switch (*iarg) {
+ v4l_dbg(1, debug, client, "set norm\n");
+ switch (*iarg) {
case VIDEO_MODE_NTSC:
- dprintk(1, "NTSC\n");
+ v4l_dbg(1, debug, client, "NTSC\n");
decoder->reg[REG_ADDR(0x06)] =
SAA_7114_NTSC_HSYNC_START;
decoder->reg[REG_ADDR(0x07)] =
@@ -572,7 +536,7 @@ saa7114_command (struct i2c_client *client,
break;
case VIDEO_MODE_PAL:
- dprintk(1, "PAL\n");
+ v4l_dbg(1, debug, client, "PAL\n");
decoder->reg[REG_ADDR(0x06)] =
SAA_7114_PAL_HSYNC_START;
decoder->reg[REG_ADDR(0x07)] =
@@ -591,9 +555,8 @@ saa7114_command (struct i2c_client *client,
break;
default:
- dprintk(1, " Unknown video mode!!!\n");
+ v4l_dbg(1, debug, client, "Unknown video mode\n");
return -EINVAL;
-
}
@@ -645,22 +608,20 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
decoder->norm = *iarg;
- }
break;
+ }
case DECODER_SET_INPUT:
{
int *iarg = arg;
- dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
if (*iarg < 0 || *iarg > 7) {
return -EINVAL;
}
if (decoder->input != *iarg) {
- dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
- I2C_NAME(client),
+ v4l_dbg(1, debug, client, "now setting %s input\n",
*iarg >= 6 ? "S-Video" : "Composite");
decoder->input = *iarg;
@@ -691,30 +652,29 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x0e,
decoder->reg[REG_ADDR(0x0e)]);
}
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_DEBUG "%s: decoder set output\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "set output\n");
/* not much choice of outputs */
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
int enable = (*iarg != 0);
- dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
- I2C_NAME(client), enable ? "enable" : "disable");
+ v4l_dbg(1, debug, client, "%s output\n",
+ enable ? "enable" : "disable");
decoder->playback = !enable;
@@ -755,18 +715,16 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x80, 0x36);
}
- }
break;
+ }
case DECODER_SET_PICTURE:
{
struct video_picture *pic = arg;
- dprintk(1,
- KERN_DEBUG
- "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
- I2C_NAME(client), pic->brightness, pic->contrast,
- pic->colour, pic->hue);
+ v4l_dbg(1, debug, client,
+ "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
+ pic->brightness, pic->contrast, pic->colour, pic->hue);
if (decoder->bright != pic->brightness) {
/* We want 0 to 255 we get 0-65535 */
@@ -790,8 +748,8 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x0d,
(decoder->hue - 32768) >> 8);
}
- }
break;
+ }
default:
return -EINVAL;
@@ -802,58 +760,30 @@ saa7114_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
- { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_saa7114;
+I2C_CLIENT_INSMOD;
-static int
-saa7114_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7114_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i, err[30];
short int hoff = SAA_7114_NTSC_HOFFSET;
short int voff = SAA_7114_NTSC_VOFFSET;
short int w = SAA_7114_NTSC_WIDTH;
short int h = SAA_7114_NTSC_HEIGHT;
- struct i2c_client *client;
struct saa7114 *decoder;
- dprintk(1,
- KERN_INFO
- "saa7114.c: detecting saa7114 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7114;
- strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
+ if (decoder == NULL)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = -1;
decoder->enable = 1;
@@ -938,8 +868,7 @@ saa7114_detect_client (struct i2c_adapter *adapter,
decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
- dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "starting init\n");
err[0] =
saa7114_write_block(client, decoder->reg + (0x20 << 1),
@@ -963,28 +892,23 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 0; i <= 5; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
for (i = 6; i < 8; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
- dprintk(1,
- KERN_DEBUG
- "%s_attach: performing decoder reset sequence\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client,
+ "performing decoder reset sequence\n");
err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
@@ -992,19 +916,15 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 6; i <= 8; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
- dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
- I2C_NAME(client));
-
+ v4l_dbg(1, debug, client, "performing the rest of init\n");
err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
@@ -1040,37 +960,32 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 9; i <= 18; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
for (i = 6; i < 8; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
for (i = 0x11; i <= 0x13; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
- dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "setting video input\n");
err[19] =
saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
@@ -1081,20 +996,15 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 19; i <= 21; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
- dprintk(1,
- KERN_DEBUG
- "%s_attach: performing decoder reset sequence\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
@@ -1103,13 +1013,11 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 22; i <= 24; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
@@ -1117,101 +1025,49 @@ saa7114_detect_client (struct i2c_adapter *adapter,
err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x, decoder status 0x%02x\n",
- I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
+ v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
+ saa7114_read(client, 0x00) >> 4,
saa7114_read(client, 0x1f));
- dprintk(1,
- KERN_DEBUG
- "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
- I2C_NAME(client), saa7114_read(client, 0x88),
+ v4l_dbg(1, debug, client,
+ "power save control: 0x%02x, scaler status: 0x%02x\n",
+ saa7114_read(client, 0x88),
saa7114_read(client, 0x8f));
for (i = 0x94; i < 0x96; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
//i = saa7114_write_block(client, init, sizeof(init));
- i = 0;
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x at address 0x%x\n",
- I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
- client->addr << 1);
- }
-
return 0;
}
-static int
-saa7114_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "saa7114.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
-}
-
-static int
-saa7114_detach_client (struct i2c_client *client)
+static int saa7114_remove(struct i2c_client *client)
{
- struct saa7114 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7114 = {
- .driver = {
- .name = "saa7114",
- },
-
- .id = I2C_DRIVERID_SAA7114,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id saa7114_id[] = {
+ { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7114_id);
- .attach_adapter = saa7114_attach_adapter,
- .detach_client = saa7114_detach_client,
+#endif
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7114",
+ .driverid = I2C_DRIVERID_SAA7114,
.command = saa7114_command,
+ .probe = saa7114_probe,
+ .remove = saa7114_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = saa7114_id,
+#endif
};
-
-static int __init
-saa7114_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7114);
-}
-
-static void __exit
-saa7114_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7114);
-}
-
-module_init(saa7114_init);
-module_exit(saa7114_exit);
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index c84895fca..11a7c76bc 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -535,11 +535,16 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
struct tda1004x_config *cdec_conf,
struct tda827x_config *tuner_conf)
{
- dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
- if (dev->dvb.frontend) {
+ struct videobuf_dvb_frontend *fe0;
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+
+ fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
if (cdec_conf->i2c_gate)
- dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
- if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
+ if (dvb_attach(tda827x_attach, fe0->dvb.frontend,
cdec_conf->tuner_address,
&dev->i2c_adap, tuner_conf))
return 0;
@@ -944,12 +949,30 @@ static int dvb_init(struct saa7134_dev *dev)
{
int ret;
int attach_xc3028 = 0;
+ struct videobuf_dvb_frontend *fe0;
+
+ /* FIXME: add support for multi-frontend */
+ mutex_init(&dev->frontends.lock);
+ INIT_LIST_HEAD(&dev->frontends.frontend.felist);
+ dev->frontends.active_fe_id = 0;
+
+ printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
+
+ if (videobuf_dvb_alloc_frontend(dev, &dev->frontends, 1) == NULL) {
+ printk(KERN_ERR "%s() failed to alloc\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
/* init struct videobuf_dvb */
dev->ts.nr_bufs = 32;
dev->ts.nr_packets = 32*4;
- dev->dvb.name = dev->name;
- videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops,
+ fe0->dvb.name = dev->name;
+ videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_ALTERNATE,
@@ -959,47 +982,47 @@ static int dvb_init(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
dprintk("pinnacle 300i dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
+ fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
}
break;
case SAA7134_BOARD_AVERMEDIA_777:
case SAA7134_BOARD_AVERMEDIA_A16AR:
dprintk("avertv 777 dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
+ fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x61,
TUNER_PHILIPS_TD1316);
}
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
dprintk("AverMedia A16D dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
break;
case SAA7134_BOARD_MD7134:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&medion_cardbus,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, medion_cardbus.tuner_address,
TUNER_PHILIPS_FMD1216ME_MK3);
}
break;
case SAA7134_BOARD_PHILIPS_TOUGH:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_tu1216_60_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
case SAA7134_BOARD_FLYDVBTDUO:
@@ -1010,24 +1033,24 @@ static int dvb_init(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_PHILIPS_EUROPA:
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_europa_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
- dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
- dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
- dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+ if (fe0->dvb.frontend) {
+ dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+ fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
+ fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
}
break;
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_tu1216_61_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
case SAA7134_BOARD_KWORLD_DVBT_210:
@@ -1066,14 +1089,14 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_0) < 0)
goto dettach_frontend;
} else { /* satellite */
- dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
+ if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
0x08, 0, 0) == NULL) {
wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
goto dettach_frontend;
@@ -1083,11 +1106,11 @@ static int dvb_init(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&ads_tech_duo_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda827x_attach,dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda827x_attach,fe0->dvb.frontend,
ads_tech_duo_config.tuner_address, &dev->i2c_adap,
&ads_duo_cfg) == NULL) {
wprintk("no tda827x tuner found at addr: %02x\n",
@@ -1108,15 +1131,15 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_0) < 0)
goto dettach_frontend;
} else { /* satellite */
- dev->dvb.frontend = dvb_attach(tda10086_attach,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap);
- if (dev->dvb.frontend) {
- struct dvb_frontend *fe = dev->dvb.frontend;
+ if (fe0->dvb.frontend) {
+ struct dvb_frontend *fe = fe0->dvb.frontend;
u8 dev_id = dev->eedata[2];
u8 data = 0xc4;
struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
- if (dvb_attach(tda826x_attach, dev->dvb.frontend,
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend,
0x60, &dev->i2c_adap, 0) == NULL) {
wprintk("%s: Medion Quadro, no tda826x "
"found !\n", __func__);
@@ -1150,31 +1173,31 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
- dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
+ fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
&dev->i2c_adap);
- if (dev->dvb.frontend)
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ if (fe0->dvb.frontend)
+ dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61,
NULL, DVB_PLL_TDHU2);
break;
case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
case SAA7134_BOARD_KWORLD_ATSC110:
- dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
+ fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
&dev->i2c_adap);
- if (dev->dvb.frontend)
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend)
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x61,
TUNER_PHILIPS_TUV1236D);
break;
case SAA7134_BOARD_FLYDVBS_LR300:
- dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(isl6421_attach, dev->dvb.frontend,
+ if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
wprintk("%s: No ISL6421 found!\n", __func__);
goto dettach_frontend;
@@ -1182,25 +1205,25 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&medion_cardbus,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
- dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+ if (fe0->dvb.frontend) {
+ dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+ fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, medion_cardbus.tuner_address,
TUNER_PHILIPS_FMD1216ME_MK3);
}
break;
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_europa_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
}
break;
case SAA7134_BOARD_CINERGY_HT_PCMCIA:
@@ -1239,15 +1262,15 @@ static int dvb_init(struct saa7134_dev *dev)
goto dettach_frontend;
break;
case SAA7134_BOARD_PHILIPS_SNAKE:
- dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+ if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0, 0) == NULL) {
wprintk("%s: No lnbp21 found!\n", __func__);
goto dettach_frontend;
@@ -1269,7 +1292,7 @@ static int dvb_init(struct saa7134_dev *dev)
saa7134_set_gpio(dev, 25, 0);
msleep(10);
saa7134_set_gpio(dev, 25, 1);
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
@@ -1279,18 +1302,18 @@ static int dvb_init(struct saa7134_dev *dev)
case SAA7134_BOARD_VIDEOMATE_T750:
#endif
case SAA7134_BOARD_MD7134_BRIDGE_2:
- dev->dvb.frontend = dvb_attach(tda10086_attach,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach,
&sd1878_4m, &dev->i2c_adap);
- if (dev->dvb.frontend) {
+ if (fe0->dvb.frontend) {
struct dvb_frontend *fe;
- if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
&dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
wprintk("%s: MD7134 DVB-S, no SD1878 "
"found !\n", __func__);
goto dettach_frontend;
}
/* we need to open the i2c gate (we know it exists) */
- fe = dev->dvb.frontend;
+ fe = fe0->dvb.frontend;
fe->ops.i2c_gate_ctrl(fe, 1);
if (dvb_attach(isl6405_attach, fe,
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
@@ -1309,7 +1332,7 @@ static int dvb_init(struct saa7134_dev *dev)
saa7134_set_gpio(dev, 25, 0);
msleep(10);
saa7134_set_gpio(dev, 25, 1);
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
@@ -1320,17 +1343,17 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_2) < 0)
goto dettach_frontend;
} else { /* satellite */
- dev->dvb.frontend = dvb_attach(tda10086_attach,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap);
- if (dev->dvb.frontend) {
+ if (fe0->dvb.frontend) {
if (dvb_attach(tda826x_attach,
- dev->dvb.frontend, 0x60,
+ fe0->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: Asus Tiger 3in1, no "
"tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+ if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0, 0) == NULL) {
wprintk("%s: Asus Tiger 3in1, no lnbp21"
" found!\n", __func__);
@@ -1356,10 +1379,10 @@ static int dvb_init(struct saa7134_dev *dev)
.i2c_addr = 0x61,
};
- if (!dev->dvb.frontend)
+ if (!fe0->dvb.frontend)
return -1;
- fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
if (!fe) {
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->name);
@@ -1367,40 +1390,47 @@ static int dvb_init(struct saa7134_dev *dev)
}
}
- if (NULL == dev->dvb.frontend) {
+ if (NULL == fe0->dvb.frontend) {
printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
return -1;
}
/* define general-purpose callback pointer */
- dev->dvb.frontend->callback = saa7134_tuner_callback;
+ fe0->dvb.frontend->callback = saa7134_tuner_callback;
/* register everything else */
- ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev,
- adapter_nr);
+ ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+ &dev->pci->dev, adapter_nr, 0);
/* this sequence is necessary to make the tda1004x load its firmware
* and to enter analog mode of hybrid boards
*/
if (!ret) {
- if (dev->dvb.frontend->ops.init)
- dev->dvb.frontend->ops.init(dev->dvb.frontend);
- if (dev->dvb.frontend->ops.sleep)
- dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
- if (dev->dvb.frontend->ops.tuner_ops.sleep)
- dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
+ if (fe0->dvb.frontend->ops.init)
+ fe0->dvb.frontend->ops.init(fe0->dvb.frontend);
+ if (fe0->dvb.frontend->ops.sleep)
+ fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend);
+ if (fe0->dvb.frontend->ops.tuner_ops.sleep)
+ fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend);
}
return ret;
dettach_frontend:
- if (dev->dvb.frontend)
- dvb_frontend_detach(dev->dvb.frontend);
- dev->dvb.frontend = NULL;
+ if (fe0->dvb.frontend)
+ dvb_frontend_detach(fe0->dvb.frontend);
+ fe0->dvb.frontend = NULL;
return -1;
}
static int dvb_fini(struct saa7134_dev *dev)
{
+ struct videobuf_dvb_frontend *fe0;
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
+
/* FIXME: I suspect that this code is bogus, since the entry for
Pinnacle 300I DVB-T PAL already defines the proper init to allow
the detection of mt2032 (TDA9887_PORT2_INACTIVE)
@@ -1420,7 +1450,7 @@ static int dvb_fini(struct saa7134_dev *dev)
u8 data = 0x80;
struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
struct dvb_frontend *fe;
- fe = dev->dvb.frontend;
+ fe = fe0->dvb.frontend;
if (fe->ops.i2c_gate_ctrl) {
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(&dev->i2c_adap, &msg, 1);
@@ -1428,8 +1458,8 @@ static int dvb_fini(struct saa7134_dev *dev)
}
}
}
- if (dev->dvb.frontend)
- videobuf_dvb_unregister(&dev->dvb);
+ if (fe0->dvb.frontend)
+ videobuf_dvb_unregister_bus(&dev->frontends);
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index 502cbe60c..837fc5424 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -586,7 +586,7 @@ struct saa7134_dev {
#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
/* SAA7134_MPEG_DVB only */
- struct videobuf_dvb dvb;
+ struct videobuf_dvb_frontends frontends;
int (*original_demod_sleep)(struct dvb_frontend *fe);
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c
index 7a6c9c1fb..195e2f415 100644
--- a/linux/drivers/media/video/saa7185.c
+++ b/linux/drivers/media/video/saa7185.c
@@ -25,24 +25,15 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
#include "compat.h"
MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
@@ -50,19 +41,10 @@ MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct saa7185 {
@@ -76,32 +58,24 @@ struct saa7185 {
int sat;
};
-#define I2C_SAA7185 0x88
-
/* ----------------------------------------------------------------------- */
-static inline int
-saa7185_read (struct i2c_client *client)
+static inline int saa7185_read(struct i2c_client *client)
{
return i2c_smbus_read_byte(client);
}
-static int
-saa7185_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static int saa7185_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7185 *encoder = i2c_get_clientdata(client);
- dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value);
+ v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value);
encoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int
-saa7185_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7185_write_block(struct i2c_client *client,
+ const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -122,18 +96,17 @@ saa7185_write_block (struct i2c_client *client,
encoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = saa7185_write(client, reg,
- *data++)) < 0)
+ ret = saa7185_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -241,15 +214,11 @@ static const unsigned char init_ntsc[] = {
0x66, 0x21, /* FSC3 */
};
-static int
-saa7185_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7185 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
saa7185_write_block(client, init_common,
sizeof(init_common));
@@ -265,7 +234,6 @@ saa7185_command (struct i2c_client *client,
sizeof(init_pal));
break;
}
-
break;
case ENCODER_GET_CAPABILITIES:
@@ -277,8 +245,8 @@ saa7185_command (struct i2c_client *client,
VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
cap->inputs = 1;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
@@ -287,7 +255,6 @@ saa7185_command (struct i2c_client *client,
//saa7185_write_block(client, init_common, sizeof(init_common));
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
saa7185_write_block(client, init_ntsc,
sizeof(init_ntsc));
@@ -301,11 +268,10 @@ saa7185_command (struct i2c_client *client,
case VIDEO_MODE_SECAM:
default:
return -EINVAL;
-
}
encoder->norm = *iarg;
- }
break;
+ }
case ENCODER_SET_INPUT:
{
@@ -315,7 +281,6 @@ saa7185_command (struct i2c_client *client,
*iarg = 1: input is from ZR36060 */
switch (*iarg) {
-
case 0:
/* Switch RTCE to 1 */
saa7185_write(client, 0x61,
@@ -333,21 +298,19 @@ saa7185_command (struct i2c_client *client,
default:
return -EINVAL;
-
}
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
@@ -357,8 +320,8 @@ saa7185_command (struct i2c_client *client,
saa7185_write(client, 0x61,
(encoder->reg[0x61] & 0xbf) |
(encoder->enable ? 0x00 : 0x40));
- }
break;
+ }
default:
return -EINVAL;
@@ -369,138 +332,69 @@ saa7185_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-static unsigned short ignore = I2C_CLIENT_END;
+I2C_CLIENT_INSMOD;
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver i2c_driver_saa7185;
-
-static int
-saa7185_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7185_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
- struct i2c_client *client;
struct saa7185 *encoder;
- dprintk(1,
- KERN_INFO
- "saa7185.c: detecting saa7185 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7185;
- strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
i = saa7185_write_block(client, init_common, sizeof(init_common));
- if (i >= 0) {
- i = saa7185_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- }
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init error %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %d at address 0x%x\n",
- I2C_NAME(client), saa7185_read(client) >> 5,
- client->addr << 1);
- }
-
+ if (i >= 0)
+ i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc));
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init error %d\n", i);
+ else
+ v4l_dbg(1, debug, client, "revision 0x%x\n",
+ saa7185_read(client) >> 5);
return 0;
}
-static int
-saa7185_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "saa7185.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7185_detect_client);
-}
-
-static int
-saa7185_detach_client (struct i2c_client *client)
+static int saa7185_remove(struct i2c_client *client)
{
struct saa7185 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
//saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
kfree(encoder);
- kfree(client);
-
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7185 = {
- .driver = {
- .name = "saa7185", /* name */
- },
-
- .id = I2C_DRIVERID_SAA7185B,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id saa7185_id[] = {
+ { "saa7185", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7185_id);
+#endif
- .attach_adapter = saa7185_attach_adapter,
- .detach_client = saa7185_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7185",
+ .driverid = I2C_DRIVERID_SAA7185B,
.command = saa7185_command,
+ .probe = saa7185_probe,
+ .remove = saa7185_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = saa7185_id,
+#endif
};
-
-static int __init
-saa7185_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7185);
-}
-
-static void __exit
-saa7185_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7185);
-}
-
-module_init(saa7185_init);
-module_exit(saa7185_exit);
diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c
index 8c1817a47..f606300e8 100644
--- a/linux/drivers/media/video/stk-webcam.c
+++ b/linux/drivers/media/video/stk-webcam.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/kref.h>
#include <linux/usb.h>
#include <linux/mm.h>
@@ -561,7 +560,7 @@ static void stk_clean_iso(struct stk_camera *dev)
urb = dev->isobufs[i].urb;
if (urb) {
- if (atomic_read(&dev->urbs_used))
+ if (atomic_read(&dev->urbs_used) && is_present(dev))
usb_kill_urb(urb);
usb_free_urb(urb);
}
@@ -690,18 +689,14 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
{
struct stk_camera *dev = fp->private_data;
- if (dev->owner != fp) {
- usb_autopm_put_interface(dev->interface);
- return 0;
+ if (dev->owner == fp) {
+ stk_stop_stream(dev);
+ stk_free_buffers(dev);
+ dev->owner = NULL;
}
- stk_stop_stream(dev);
-
- stk_free_buffers(dev);
-
- dev->owner = NULL;
-
- usb_autopm_put_interface(dev->interface);
+ if(is_present(dev))
+ usb_autopm_put_interface(dev->interface);
return 0;
}
@@ -715,9 +710,6 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
struct stk_sio_buffer *sbuf;
struct stk_camera *dev = fp->private_data;
- if (dev == NULL)
- return -EIO;
-
if (!is_present(dev))
return -EIO;
if (dev->owner && dev->owner != fp)
@@ -774,9 +766,6 @@ static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
{
struct stk_camera *dev = fp->private_data;
- if (dev == NULL)
- return -ENODEV;
-
poll_wait(fp, &dev->wait_frame, wait);
if (!is_present(dev))
@@ -1437,7 +1426,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
wake_up_interruptible(&dev->wait_frame);
stk_remove_sysfs_files(&dev->vdev);
- STK_INFO("Syntek USB2.0 Camera release resources"
+ STK_INFO("Syntek USB2.0 Camera release resources "
"video device /dev/video%d\n", dev->vdev.minor);
video_unregister_device(&dev->vdev);
diff --git a/linux/drivers/media/video/stk-webcam.h b/linux/drivers/media/video/stk-webcam.h
index 084a85bdd..9f6736637 100644
--- a/linux/drivers/media/video/stk-webcam.h
+++ b/linux/drivers/media/video/stk-webcam.h
@@ -122,7 +122,6 @@ struct stk_camera {
#define vdev_to_camera(d) container_of(d, struct stk_camera, vdev)
-void stk_camera_delete(struct kref *);
int stk_camera_write_reg(struct stk_camera *, u16, u8);
int stk_camera_read_reg(struct stk_camera *, u16, int *);
diff --git a/linux/drivers/media/video/videobuf-dvb.c b/linux/drivers/media/video/videobuf-dvb.c
index d9979ab26..33e2f2b2b 100644
--- a/linux/drivers/media/video/videobuf-dvb.c
+++ b/linux/drivers/media/video/videobuf-dvb.c
@@ -140,29 +140,78 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
}
/* ------------------------------------------------------------------ */
+/* Register a single adapter and one or more frontends */
+int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
+ struct module *module,
+ void *adapter_priv,
+ struct device *device,
+ short *adapter_nr,
+ int mfe_shared)
+{
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe;
+ int res = -EINVAL;
+
+ fe = videobuf_dvb_get_frontend(f, 1);
+ if (!fe) {
+ printk(KERN_WARNING "Unable to register the adapter which has no frontends\n");
+ goto err;
+ }
+
+ /* Bring up the adapter */
+ res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, fe->dvb.name, adapter_nr, mfe_shared);
+ if (res < 0) {
+ printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
+ goto err;
+ }
-int videobuf_dvb_register(struct videobuf_dvb *dvb,
+ /* Attach all of the frontends to the adapter */
+ mutex_lock(&f->lock);
+ list_for_each_safe(list, q, &f->frontend.felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+
+ res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb);
+ if (res < 0) {
+ printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n",
+ fe->dvb.name, res);
+ }
+ }
+ mutex_unlock(&f->lock);
+
+err:
+ return res;
+}
+
+int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
struct module *module,
void *adapter_priv,
struct device *device,
- short *adapter_nr)
+ char *adapter_name,
+ short *adapter_nr,
+ int mfe_shared)
{
int result;
- mutex_init(&dvb->lock);
+ mutex_init(&fe->lock);
/* register adapter */
- result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device,
- adapter_nr);
+ result = dvb_register_adapter(&fe->adapter, adapter_name, module, device, adapter_nr);
if (result < 0) {
printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
- dvb->name, result);
- goto fail_adapter;
+ adapter_name, result);
}
- dvb->adapter.priv = adapter_priv;
+ fe->adapter.priv = adapter_priv;
+ fe->adapter.mfe_shared = mfe_shared;
+
+ return result;
+}
+
+int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb)
+{
+ int result;
/* register frontend */
- result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+ result = dvb_register_frontend(adapter, dvb->frontend);
if (result < 0) {
printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
dvb->name, result);
@@ -188,7 +237,8 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
dvb->dmxdev.filternum = 256;
dvb->dmxdev.demux = &dvb->demux.dmx;
dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+ result = dvb_dmxdev_init(&dvb->dmxdev, adapter);
+
if (result < 0) {
printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
dvb->name, result);
@@ -219,7 +269,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
}
/* register network adapter */
- dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+ dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
return 0;
fail_fe_conn:
@@ -234,25 +284,102 @@ fail_dmx:
dvb_unregister_frontend(dvb->frontend);
fail_frontend:
dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
+ dvb_unregister_adapter(adapter);
+
return result;
}
-void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
+void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
{
- dvb_net_release(&dvb->net);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- dvb_unregister_frontend(dvb->frontend);
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe;
+
+ mutex_lock(&f->lock);
+ list_for_each_safe(list, q, &f->frontend.felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+
+ dvb_net_release(&fe->dvb.net);
+ fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, &fe->dvb.fe_mem);
+ fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, &fe->dvb.fe_hw);
+ dvb_dmxdev_release(&fe->dvb.dmxdev);
+ dvb_dmx_release(&fe->dvb.demux);
+ dvb_unregister_frontend(fe->dvb.frontend);
+ dvb_frontend_detach(fe->dvb.frontend);
+
+ list_del(list);
+ kfree(fe);
+ }
+ mutex_unlock(&f->lock);
+
+ dvb_unregister_adapter(&f->adapter);
+}
+
+struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id)
+{
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe, *ret = NULL;
+
+ mutex_lock(&f->lock);
+
+ list_for_each_safe(list, q, &f->frontend.felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+ if (fe->id == id) {
+ ret = fe;
+ break;
+ }
+ }
+
+ mutex_unlock(&f->lock);
+
+ return ret;
+}
+
+int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p)
+{
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe = NULL;
+ int ret = 0;
+
+ mutex_lock(&f->lock);
+
+ list_for_each_safe(list, q, &f->frontend.felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+ if (fe->dvb.frontend == p) {
+ ret = fe->id;
+ break;
+ }
+ }
+
+ mutex_unlock(&f->lock);
+
+ return ret;
+}
+
+struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(void *private, struct videobuf_dvb_frontends *f, int id)
+{
+ struct videobuf_dvb_frontend *fe;
+
+ fe = kzalloc(sizeof(struct videobuf_dvb_frontend),GFP_KERNEL);
+ if (fe == NULL)
+ goto fail_alloc;
+
+ fe->dev = private;
+ fe->id = id;
+ mutex_init(&fe->dvb.lock);
+
+ mutex_lock(&f->lock);
+ list_add_tail(&fe->felist,&f->frontend.felist);
+ mutex_unlock(&f->lock);
+
+fail_alloc:
+ return fe;
}
-EXPORT_SYMBOL(videobuf_dvb_register);
-EXPORT_SYMBOL(videobuf_dvb_unregister);
+EXPORT_SYMBOL(videobuf_dvb_register_bus);
+EXPORT_SYMBOL(videobuf_dvb_unregister_bus);
+EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);
+EXPORT_SYMBOL(videobuf_dvb_get_frontend);
+EXPORT_SYMBOL(videobuf_dvb_find_frontend);
/* ------------------------------------------------------------------ */
/*
diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c
index 896af1a12..5f368a1be 100644
--- a/linux/drivers/media/video/vpx3220.c
+++ b/linux/drivers/media/video/vpx3220.c
@@ -22,33 +22,22 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/types.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
#include <asm/uaccess.h>
-
#include <linux/i2c.h>
-
-#define I2C_NAME(x) (x)->name
-
-#include "compat.h"
-#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev.h>
#include <linux/video_decoder.h>
+#include "compat.h"
-#define I2C_VPX3220 0x86
-#define VPX3220_DEBUG KERN_DEBUG "vpx3220: "
+MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
+MODULE_AUTHOR("Laurent Pinchart");
+MODULE_LICENSE("GPL");
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
#define VPX_TIMEOUT_COUNT 10
/* ----------------------------------------------------------------------- */
@@ -68,10 +57,8 @@ struct vpx3220 {
static char *inputs[] = { "internal", "composite", "svideo" };
/* ----------------------------------------------------------------------- */
-static inline int
-vpx3220_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+
+static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value)
{
struct vpx3220 *decoder = i2c_get_clientdata(client);
@@ -79,15 +66,12 @@ vpx3220_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-vpx3220_read (struct i2c_client *client,
- u8 reg)
+static inline int vpx3220_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-vpx3220_fp_status (struct i2c_client *client)
+static int vpx3220_fp_status(struct i2c_client *client)
{
unsigned char status;
unsigned int i;
@@ -107,14 +91,11 @@ vpx3220_fp_status (struct i2c_client *client)
return -1;
}
-static int
-vpx3220_fp_write (struct i2c_client *client,
- u8 fpaddr,
- u16 data)
+static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data)
{
/* Write the 16-bit address to the FPWR register */
if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
@@ -123,22 +104,20 @@ vpx3220_fp_write (struct i2c_client *client,
/* Write the 16-bit data to the FPDAT register */
if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
return 0;
}
-static u16
-vpx3220_fp_read (struct i2c_client *client,
- u16 fpaddr)
+static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr)
{
s16 data;
/* Write the 16-bit address to the FPRD register */
if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
@@ -148,25 +127,22 @@ vpx3220_fp_read (struct i2c_client *client,
/* Read the 16-bit data from the FPDAT register */
data = i2c_smbus_read_word_data(client, 0x28);
if (data == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
return swab16(data);
}
-static int
-vpx3220_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
u8 reg;
int ret = -1;
while (len >= 2) {
reg = *data++;
- if ((ret =
- vpx3220_write(client, reg, *data++)) < 0)
+ ret = vpx3220_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -174,10 +150,8 @@ vpx3220_write_block (struct i2c_client *client,
return ret;
}
-static int
-vpx3220_write_fp_block (struct i2c_client *client,
- const u16 *data,
- unsigned int len)
+static int vpx3220_write_fp_block(struct i2c_client *client,
+ const u16 *data, unsigned int len)
{
u8 reg;
int ret = 0;
@@ -286,25 +260,20 @@ static const unsigned short init_fp[] = {
0x4b, 0x298, /* PLL gain */
};
-static void
-vpx3220_dump_i2c (struct i2c_client *client)
+static void vpx3220_dump_i2c(struct i2c_client *client)
{
int len = sizeof(init_common);
const unsigned char *data = init_common;
while (len > 1) {
- dprintk(1,
- KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n",
+ v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
*data, vpx3220_read(client, *data));
data += 2;
len -= 2;
}
}
-static int
-vpx3220_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct vpx3220 *decoder = i2c_get_clientdata(client);
@@ -316,7 +285,6 @@ vpx3220_command (struct i2c_client *client,
vpx3220_write_fp_block(client, init_fp,
sizeof(init_fp) >> 1);
switch (decoder->norm) {
-
case VIDEO_MODE_NTSC:
vpx3220_write_fp_block(client, init_ntsc,
sizeof(init_ntsc) >> 1);
@@ -335,21 +303,20 @@ vpx3220_command (struct i2c_client *client,
sizeof(init_pal) >> 1);
break;
}
- }
break;
+ }
case DECODER_DUMP:
{
vpx3220_dump_i2c(client);
- }
break;
+ }
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
- dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
@@ -358,20 +325,18 @@ vpx3220_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 3;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
int res = 0, status;
- dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
status = vpx3220_fp_read(client, 0x0f3);
- dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status: 0x%04x\n", status);
if (status < 0)
return status;
@@ -380,7 +345,6 @@ vpx3220_command (struct i2c_client *client,
res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
switch (status & 0x18) {
-
case 0x00:
case 0x10:
case 0x14:
@@ -401,8 +365,8 @@ vpx3220_command (struct i2c_client *client,
}
*(int *) arg = res;
- }
break;
+ }
case DECODER_SET_NORM:
{
@@ -414,50 +378,43 @@ vpx3220_command (struct i2c_client *client,
choosen video norm */
temp_input = vpx3220_fp_read(client, 0xf2);
- dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
vpx3220_write_fp_block(client, init_ntsc,
sizeof(init_ntsc) >> 1);
- dprintk(1, KERN_INFO "%s: norm switched to NTSC\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to NTSC\n");
break;
case VIDEO_MODE_PAL:
vpx3220_write_fp_block(client, init_pal,
sizeof(init_pal) >> 1);
- dprintk(1, KERN_INFO "%s: norm switched to PAL\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to PAL\n");
break;
case VIDEO_MODE_SECAM:
vpx3220_write_fp_block(client, init_secam,
sizeof(init_secam) >> 1);
- dprintk(1, KERN_INFO "%s: norm switched to SECAM\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to SECAM\n");
break;
case VIDEO_MODE_AUTO:
/* FIXME This is only preliminary support */
data = vpx3220_fp_read(client, 0xf2) & 0x20;
vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
- dprintk(1, KERN_INFO "%s: norm switched to Auto\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to AUTO\n");
break;
default:
return -EINVAL;
-
}
decoder->norm = *iarg;
/* And here we set the backed up video input again */
vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
udelay(10);
- }
break;
+ }
case DECODER_SET_INPUT:
{
@@ -476,8 +433,7 @@ vpx3220_command (struct i2c_client *client,
if (*iarg < 0 || *iarg > 2)
return -EINVAL;
- dprintk(1, KERN_INFO "%s: input switched to %s\n",
- I2C_NAME(client), inputs[*iarg]);
+ v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
vpx3220_write(client, 0x33, input[*iarg][0]);
@@ -489,8 +445,8 @@ vpx3220_command (struct i2c_client *client,
data | (input[*iarg][1] << 5) | 0x0010);
udelay(10);
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
@@ -500,19 +456,18 @@ vpx3220_command (struct i2c_client *client,
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
- }
break;
+ }
case DECODER_SET_PICTURE:
{
@@ -543,8 +498,8 @@ vpx3220_command (struct i2c_client *client,
vpx3220_fp_write(client, 0x1c,
((decoder->hue - 32768) >> 6) & 0xFFF);
}
- }
break;
+ }
default:
return -EINVAL;
@@ -553,8 +508,7 @@ vpx3220_command (struct i2c_client *client,
return 0;
}
-static int
-vpx3220_init_client (struct i2c_client *client)
+static int vpx3220_init_client(struct i2c_client *client)
{
vpx3220_write_block(client, init_common, sizeof(init_common));
vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
@@ -568,115 +522,26 @@ vpx3220_init_client (struct i2c_client *client)
* Client management code
*/
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
- { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4,
- I2C_CLIENT_END
-};
+static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END };
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver vpx3220_i2c_driver;
-
-static int
-vpx3220_detach_client (struct i2c_client *client)
-{
- struct vpx3220 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
- return 0;
-}
+I2C_CLIENT_INSMOD;
-static int
-vpx3220_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int vpx3220_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int err;
- struct i2c_client *client;
struct vpx3220 *decoder;
-
- dprintk(1, VPX3220_DEBUG "%s\n", __func__);
+ const char *name = NULL;
+ u8 ver;
+ u16 pn;
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality
- (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
- return 0;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == NULL) {
- return -ENOMEM;
- }
-
- client->addr = address;
- client->adapter = adapter;
- client->driver = &vpx3220_i2c_driver;
-
- /* Check for manufacture ID and part number */
- if (kind < 0) {
- u8 id;
- u16 pn;
-
- id = vpx3220_read(client, 0x00);
- if (id != 0xec) {
- dprintk(1,
- KERN_INFO
- "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n",
- id);
- kfree(client);
- return 0;
- }
-
- pn = (vpx3220_read(client, 0x02) << 8) +
- vpx3220_read(client, 0x01);
- switch (pn) {
- case 0x4680:
- strlcpy(I2C_NAME(client), "vpx3220a",
- sizeof(I2C_NAME(client)));
- break;
- case 0x4260:
- strlcpy(I2C_NAME(client), "vpx3216b",
- sizeof(I2C_NAME(client)));
- break;
- case 0x4280:
- strlcpy(I2C_NAME(client), "vpx3214c",
- sizeof(I2C_NAME(client)));
- break;
- default:
- dprintk(1,
- KERN_INFO
- "%s: Wrong part number (0x%04x)\n",
- __func__, pn);
- kfree(client);
- return 0;
- }
- } else {
- strlcpy(I2C_NAME(client), "forced vpx32xx",
- sizeof(I2C_NAME(client)));
- }
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+ return -ENODEV;
decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
+ if (decoder == NULL)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_PAL;
decoder->input = 0;
decoder->enable = 1;
@@ -686,63 +551,56 @@ vpx3220_detect_client (struct i2c_adapter *adapter,
decoder->sat = 32768;
i2c_set_clientdata(client, decoder);
- err = i2c_attach_client(client);
- if (err) {
- kfree(client);
- kfree(decoder);
- return err;
+ ver = i2c_smbus_read_byte_data(client, 0x00);
+ pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
+ i2c_smbus_read_byte_data(client, 0x01);
+ if (ver == 0xec) {
+ switch (pn) {
+ case 0x4680:
+ name = "vpx3220a";
+ break;
+ case 0x4260:
+ name = "vpx3216b";
+ break;
+ case 0x4280:
+ name = "vpx3214c";
+ break;
+ }
}
-
- dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n",
- I2C_NAME(client), client->addr << 1);
+ if (name)
+ v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ client->addr << 1, client->adapter->name);
+ else
+ v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n",
+ ver, pn, client->addr << 1, client->adapter->name);
vpx3220_init_client(client);
-
return 0;
}
-static int
-vpx3220_attach_adapter (struct i2c_adapter *adapter)
+static int vpx3220_remove(struct i2c_client *client)
{
- int ret;
-
- ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client);
- dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n",
- __func__, ret);
- return ret;
+ kfree(i2c_get_clientdata(client));
+ return 0;
}
-/* -----------------------------------------------------------------------
- * Driver initialization and cleanup code
- */
-
-static struct i2c_driver vpx3220_i2c_driver = {
- .driver = {
- .name = "vpx3220",
- },
-
- .id = I2C_DRIVERID_VPX3220,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+static const struct i2c_device_id vpx3220_id[] = {
+ { "vpx3220a", 0 },
+ { "vpx3216b", 0 },
+ { "vpx3214c", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, vpx3220_id);
+#endif
- .attach_adapter = vpx3220_attach_adapter,
- .detach_client = vpx3220_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "vpx3220",
+ .driverid = I2C_DRIVERID_VPX3220,
.command = vpx3220_command,
+ .probe = vpx3220_probe,
+ .remove = vpx3220_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+ .id_table = vpx3220_id,
+#endif
};
-
-static int __init
-vpx3220_init (void)
-{
- return i2c_add_driver(&vpx3220_i2c_driver);
-}
-
-static void __exit
-vpx3220_cleanup (void)
-{
- i2c_del_driver(&vpx3220_i2c_driver);
-}
-
-module_init(vpx3220_init);
-module_exit(vpx3220_cleanup);
-
-MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
-MODULE_AUTHOR("Laurent Pinchart");
-MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c
index 081b72a45..d5026ae51 100644
--- a/linux/drivers/media/video/zoran/zoran_card.c
+++ b/linux/drivers/media/video/zoran/zoran_card.c
@@ -818,6 +818,7 @@ zoran_register_i2c (struct zoran *zr)
memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
sizeof(struct i2c_algo_bit_data));
zr->i2c_algo.data = zr;
+ zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
zr->i2c_adapter.id = I2C_HW_B_ZR36067;
zr->i2c_adapter.client_register = zoran_i2c_client_register;
zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;