Commit cc26b076 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB (11369): v4l2-subdev: add load_fw and use that instead of abusing core->init.

The init callback was used in several places to load firmware. Make a separate
load_fw callback for that. This makes the code a lot more understandable.
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 7c9fc9d5
......@@ -203,11 +203,8 @@ static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
{
struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
switch (val) {
case CX18_AV_INIT_PLLS:
/*
* The crystal freq used in calculations in this driver will be
* 28.636360 MHz.
......@@ -230,17 +227,19 @@ static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
break;
return 0;
}
static int cx18_av_load_fw(struct v4l2_subdev *sd)
{
struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
case CX18_AV_INIT_NORMAL:
default:
if (!state->is_initialized) {
/* initialize on first use */
state->is_initialized = 1;
cx18_av_initialize(cx);
}
break;
}
return 0;
}
......@@ -1185,6 +1184,7 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
.g_chip_ident = cx18_av_g_chip_ident,
.log_status = cx18_av_log_status,
.init = cx18_av_init,
.load_fw = cx18_av_load_fw,
.reset = cx18_av_reset,
.queryctrl = cx18_av_queryctrl,
.g_ctrl = cx18_av_g_ctrl,
......
......@@ -328,11 +328,6 @@ static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
return container_of(sd, struct cx18_av_state, sd);
}
enum cx18_av_subdev_init_arg {
CX18_AV_INIT_NORMAL = 0,
CX18_AV_INIT_PLLS = 1,
};
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
......
......@@ -810,7 +810,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
CX18_ERR("Could not register A/V decoder subdevice\n");
goto free_map;
}
cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS);
cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0);
/* Initialize GPIO Reset Controller to do chip resets during i2c init */
if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
......@@ -1028,7 +1028,7 @@ int cx18_init_on_first_open(struct cx18 *cx)
cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
/* Init the A/V decoder, if it hasn't been already */
v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL);
v4l2_subdev_call(cx->sd_av, core, load_fw);
vf.tuner = 0;
vf.type = V4L2_TUNER_ANALOG_TV;
......
......@@ -316,7 +316,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
"cx25840", "cx25840", 0x88 >> 1);
if (dev->sd_cx25840 == NULL)
cx231xx_info("cx25840 subdev registration failure\n");
cx25840_call(dev, core, init, 0);
cx25840_call(dev, core, load_fw);
}
......
......@@ -741,7 +741,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
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);
v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
break;
}
......
......@@ -1182,7 +1182,7 @@ static void log_audio_status(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
/* This init operation must be called to load the driver's firmware.
/* This load_fw operation must be called to load the driver's firmware.
Without this the audio standard detection will fail and you will
only get mono.
......@@ -1192,13 +1192,13 @@ static void log_audio_status(struct i2c_client *client)
postponing it is that loading this firmware takes a long time (seconds)
due to the slow i2c bus speed. So it will speed up the boot process if
you can avoid loading the fw as long as the video device isn't used. */
static int cx25840_init(struct v4l2_subdev *sd, u32 val)
static int cx25840_load_fw(struct v4l2_subdev *sd)
{
struct cx25840_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (!state->is_initialized) {
/* initialize on first use */
/* initialize and load firmware */
state->is_initialized = 1;
if (state->is_cx25836)
cx25836_initialize(client);
......@@ -1473,7 +1473,7 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = {
.s_ctrl = cx25840_s_ctrl,
.queryctrl = cx25840_queryctrl,
.reset = cx25840_reset,
.init = cx25840_init,
.load_fw = cx25840_load_fw,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cx25840_g_register,
.s_register = cx25840_s_register,
......
......@@ -1234,7 +1234,7 @@ int ivtv_init_on_first_open(struct ivtv *itv)
if (itv->card->hw_all & IVTV_HW_CX25840) {
struct v4l2_control ctrl;
v4l2_subdev_call(itv->sd_video, core, init, 0);
v4l2_subdev_call(itv->sd_video, core, load_fw);
/* CX25840_CID_ENABLE_PVR150_WORKAROUND */
ctrl.id = V4L2_CID_PRIVATE_BASE;
ctrl.value = itv->pvr150_workaround;
......
......@@ -2185,7 +2185,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
pvr2_hdw_load_modules(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
v4l2_device_call_all(&hdw->v4l2_dev, 0, core, init, 0);
v4l2_device_call_all(&hdw->v4l2_dev, 0, core, load_fw);
for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
cptr = hdw->controls + idx;
......
......@@ -89,6 +89,8 @@ struct v4l2_crystal_freq {
values. Do not use for new drivers and should be removed in existing
drivers.
load_fw: load firmware.
reset: generic reset command. The argument selects which subsystems to
reset. Passing 0 will always reset the whole chip. Do not use for new
drivers without discussing this first on the linux-media mailinglist.
......@@ -101,6 +103,7 @@ struct v4l2_subdev_core_ops {
int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*init)(struct v4l2_subdev *sd, u32 val);
int (*load_fw)(struct v4l2_subdev *sd);
int (*reset)(struct v4l2_subdev *sd, u32 val);
int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment