diff options
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-417.c | 23 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-cards.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-core.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-dvb.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-i2c.c | 86 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-video.c | 62 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885.h | 6 |
7 files changed, 58 insertions, 127 deletions
diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c index adfb79799..aeef889fd 100644 --- a/linux/drivers/media/video/cx23885/cx23885-417.c +++ b/linux/drivers/media/video/cx23885/cx23885-417.c @@ -1194,8 +1194,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) * This will likely need to be enabled for non NTSC * formats. */ - cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_S_STD, id); - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, id); + call_all(dev, tuner, s_std, id); #endif return 0; } @@ -1259,8 +1258,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); @@ -1277,7 +1275,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; } @@ -1293,8 +1291,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; } @@ -1321,8 +1318,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); @@ -1336,7 +1332,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; } @@ -1532,12 +1528,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/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index e6db78f8b..493551ec0 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -740,7 +740,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/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index eea0bc650..2bffcbc48 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -876,7 +876,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/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 364543987..dfb16b91e 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -674,7 +674,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/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c index 86493da33..3b0b9d3e3 100644 --- a/linux/drivers/media/video/cx23885/cx23885-i2c.c +++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c @@ -269,83 +269,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 0 - if (dev->radio_type != UNSET) { - - dprintk(1, "%s (radio) i2c attach [addr=0x%x,client=%s]\n", - client->driver->driver.name, client->addr, - client->name); - - if ((dev->radio_addr == ADDR_UNSET) || - (dev->radio_addr == client->addr)) { - tun_setup.mode_mask = T_RADIO; - tun_setup.type = dev->radio_type; - tun_setup.addr = dev->radio_addr; - - client->driver->command(client, TUNER_SET_TYPE_ADDR, - &tun_setup); - } - } -#endif - - 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; @@ -366,9 +289,9 @@ static struct i2c_adapter cx23885_i2c_adap_template = { .owner = THIS_MODULE, .id = I2C_HW_B_CX23885, .algo = &cx23885_i2c_algo_template, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) .class = I2C_CLASS_TV_ANALOG, - .client_register = attach_inform, - .client_unregister = detach_inform, +#endif }; static struct i2c_client cx23885_i2c_client_template = { @@ -432,8 +355,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/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index dd6e1f70e..a45bd3b77 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -334,11 +334,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; } @@ -445,12 +441,10 @@ 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); #if 0 route.input = 0; /* Let the AVCore default */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], - VIDIOC_INT_S_AUDIO_ROUTING, &route); + v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, &route); #endif return 0; @@ -840,8 +834,7 @@ static int video_open(struct file *file) dev->tvaudio = WW_FM; cx23885_set_tvaudio(dev); cx23885_set_stereo(dev, V4L2_TUNER_MODE_STEREO, 1); - cx23885_call_i2c_clients(&dev->i2c_bus[1], - AUDC_SET_RADIO, NULL); + call_all(dev, tuner, s_radio); } #endif unlock_kernel(); @@ -944,7 +937,7 @@ static int video_release(struct file *file) * tuner video. Closing this will result in no video to the encoder. */ #if 0 - cx23885_call_i2c_clients(&dev->i2c_bus[1], TUNER_SET_STANDBY, NULL); + call_all(dev, tuner, s_standby); #endif return 0; @@ -964,7 +957,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; } @@ -974,7 +967,7 @@ static int cx23885_set_control(struct cx23885_dev *dev, dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" " (disabled - no action)\n", __func__); #if 0 - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl); + call_all(dev, core, s_ctrl, ctl); #endif return 0; } @@ -1081,7 +1074,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; } @@ -1370,7 +1363,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; } @@ -1385,7 +1378,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); @@ -1419,7 +1412,7 @@ static int vidioc_g_register(struct file *file, void *fh, if (!v4l2_chip_match_host(®->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; } @@ -1432,7 +1425,7 @@ static int vidioc_s_register(struct file *file, void *fh, if (!v4l2_chip_match_host(®->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; } @@ -1468,7 +1461,7 @@ static int radio_g_tuner(struct file *file, void *priv, strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); + call_all(dev, tuner, g_tuner, t); return 0; } @@ -1503,7 +1496,7 @@ static int radio_s_tuner(struct file *file, void *priv, if (0 != t->index) return -EINVAL; - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_TUNER, t); + call_all(dev, tuner, s_tuner, t); return 0; } @@ -1782,13 +1775,30 @@ int cx23885_video_register(struct cx23885_dev *dev) #endif cx_set(PCI_INT_MSK, 1); -#if 0 - /* FIXME: These should be correctly defined */ - /* load and configure helper modules */ - if (TUNER_ABSENT != core->tuner_type) - request_module("tuner"); + 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); + } + } + +#if 0 if (cx23885_boards[dev->board].audio_chip == V4L2_IDENT_WM8775) + /* Must use v4l2_i2c_new_subdev instead of request_module + once this is implemented for real. */ request_module("wm8775"); #endif diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 80031ddfa..c090a7df9 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -324,6 +324,7 @@ struct cx23885_dev { unsigned int radio_type; unsigned char radio_addr; unsigned int has_radio; + struct v4l2_subdev *sd_cx25840; /* V4l */ u32 freq; @@ -349,6 +350,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 */ @@ -465,8 +469,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); /* ----------------------------------------------------------- */ |