summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx23885')
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c20
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c4
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c67
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c41
-rw-r--r--drivers/media/video/cx23885/cx23885.h6
7 files changed, 47 insertions, 95 deletions
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 9e57c33b5496..6f5df90af93e 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1251,8 +1251,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
strcpy(t->name, "Television");
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+ call_all(dev, tuner, g_tuner, t);
dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
@@ -1269,7 +1268,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+ call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -1285,8 +1284,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1313,8 +1311,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return -EINVAL;
dev->freq = f->frequency;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
cx23885_initialize_codec(dev);
@@ -1328,7 +1325,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ call_all(dev, core, s_ctrl, ctl);
return 0;
}
@@ -1524,12 +1521,7 @@ static int vidioc_log_status(struct file *file, void *priv)
printk(KERN_INFO
"%s/2: ============ START LOG STATUS ============\n",
dev->name);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
- NULL);
+ call_all(dev, core, log_status);
cx2341x_log_status(&dev->mpeg_params, name);
printk(KERN_INFO
"%s/2: ============= END LOG STATUS =============\n",
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 08cd793cd151..5e4b7e790d94 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -739,7 +739,9 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- request_module("cx25840");
+ dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap,
+ "cx25840", "cx25840", 0x88 >> 1);
+ v4l2_subdev_call(dev->sd_cx25840, core, init, 0);
break;
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 548279225d73..dc7fff22cfdd 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -875,7 +875,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
cx23885_i2c_register(&dev->i2c_bus[1]);
cx23885_i2c_register(&dev->i2c_bus[2]);
cx23885_card_setup(dev);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
cx23885_ir_init(dev);
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 8d731fffad58..d43c74396767 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -673,7 +673,7 @@ static int dvb_register(struct cx23885_tsport *port)
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);
+ call_all(dev, core, s_standby, 0);
if (fe0->dvb.frontend->ops.analog_ops.standby)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 969b7ebbc827..3421bd12056a 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -268,65 +268,6 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap,
return retval;
}
-static int attach_inform(struct i2c_client *client)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
- struct cx23885_dev *dev = to_cx23885(v4l2_dev);
- struct tuner_setup tun_setup;
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- if (!client->driver->command)
- return 0;
-
- if (dev->tuner_type != UNSET) {
-
- dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr,
- client->name);
-
- if ((dev->tuner_addr == ADDR_UNSET) ||
- (dev->tuner_addr == client->addr)) {
-
- dprintk(1, "%s (tuner || addr UNSET)\n",
- client->driver->driver.name);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name,
- client->addr, client->name);
-
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
-
- client->driver->command(client, TUNER_SET_TYPE_ADDR,
- &tun_setup);
- }
- }
-
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
- struct cx23885_dev *dev = to_cx23885(v4l2_dev);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
-
- return 0;
-}
-
-void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
- unsigned int cmd, void *arg)
-{
- if (bus->i2c_rc != 0)
- return;
-
- i2c_clients_command(&bus->i2c_adap, cmd, arg);
-}
-
static u32 cx23885_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -344,9 +285,6 @@ static struct i2c_adapter cx23885_i2c_adap_template = {
.owner = THIS_MODULE,
.id = I2C_HW_B_CX23885,
.algo = &cx23885_i2c_algo_template,
- .class = I2C_CLASS_TV_ANALOG,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
};
static struct i2c_client cx23885_i2c_client_template = {
@@ -410,8 +348,11 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
if (0 == bus->i2c_rc) {
dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
- if (i2c_scan)
+ if (i2c_scan) {
+ printk(KERN_INFO "%s: scan bus %d:\n",
+ dev->name, bus->nr);
do_i2c_scan(dev->name, &bus->i2c_client);
+ }
} else
printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 1596f4ff3dfe..f0ac62c5dc83 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -299,11 +299,7 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
dev->tvnorm = norm;
- /* Tell the analog tuner/demods */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm);
-
- /* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm);
+ call_all(dev, tuner, s_std, norm);
return 0;
}
@@ -410,8 +406,7 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
route.input = INPUT(input)->vmux;
/* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2],
- VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
return 0;
}
@@ -887,7 +882,7 @@ static int cx23885_get_control(struct cx23885_dev *dev,
struct v4l2_control *ctl)
{
dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
+ call_all(dev, core, g_ctrl, ctl);
return 0;
}
@@ -1001,7 +996,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fh->vidq.field = f->fmt.pix.field;
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
fh->width, fh->height, fh->vidq.field);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f);
+ call_all(dev, video, s_fmt, f);
return 0;
}
@@ -1281,7 +1276,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1296,7 +1291,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
mutex_lock(&dev->lock);
dev->freq = f->frequency;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep(10);
@@ -1330,7 +1325,7 @@ static int vidioc_g_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);
+ call_all(dev, core, g_register, reg);
return 0;
}
@@ -1343,7 +1338,7 @@ static int vidioc_s_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);
+ call_all(dev, core, s_register, reg);
return 0;
}
@@ -1524,6 +1519,26 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* Don't enable VBI yet */
cx_set(PCI_INT_MSK, 1);
+ if (TUNER_ABSENT != dev->tuner_type) {
+ struct v4l2_subdev *sd = NULL;
+
+ if (dev->tuner_addr)
+ sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ else
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+ if (sd) {
+ struct tuner_setup tun_setup;
+
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+
+ v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+ }
+ }
+
/* register v4l devices */
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index ba57643f1198..02d980a29962 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -323,6 +323,7 @@ struct cx23885_dev {
unsigned int radio_type;
unsigned char radio_addr;
unsigned int has_radio;
+ struct v4l2_subdev *sd_cx25840;
/* V4l */
u32 freq;
@@ -348,6 +349,9 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
}
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
+
extern struct list_head cx23885_devlist;
#define SRAM_CH01 0 /* Video A */
@@ -464,8 +468,6 @@ extern struct videobuf_queue_ops cx23885_vbi_qops;
/* cx23885-i2c.c */
extern int cx23885_i2c_register(struct cx23885_i2c *bus);
extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
- void *arg);
extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
/* ----------------------------------------------------------- */