summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18/cx18-av-core.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-02-16 02:23:25 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 12:43:01 -0300
commitfa3e70360c86480acbaa54c9791e843196327a66 (patch)
treebc8d1f8b68f9aad107d63d6b6c9e884519fe1d34 /drivers/media/video/cx18/cx18-av-core.c
parent5811cf99df2e3c102055be3ea77508e56c9f77c6 (diff)
V4L/DVB (10757): cx18, v4l2-chip-ident: Finish conversion of AV decoder core to v4l2_subdev
Added a new chip identifer to v4l2-chip-ident for the integrated A/V broadcast decoder core internal to the CX23418. Completed separation and encapsulation of the A/V decoder core interface as a v4l2_subdevice. The cx18 driver now compiles and links again. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-av-core.c')
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c85
1 files changed, 62 insertions, 23 deletions
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 9b30f77b5205..f9bb77a25ee9 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -201,15 +201,45 @@ static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
return 0;
}
-static int cx18_av_init_hardware(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);
- if (!state->is_initialized) {
- /* initialize on first use */
- state->is_initialized = 1;
- cx18_av_initialize(cx);
+ switch (val) {
+ case CX18_AV_INIT_PLLS:
+ /*
+ * The crystal freq used in calculations in this driver will be
+ * 28.636360 MHz.
+ * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+ */
+
+ /*
+ * VDCLK Integer = 0x0f, Post Divider = 0x04
+ * AIMCLK Integer = 0x0e, Post Divider = 0x16
+ */
+ cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+ /* VDCLK Fraction = 0x2be2fe */
+ /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+ cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+ /* AIMCLK Fraction = 0x05227ad */
+ /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+ cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+ cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+ break;
+
+ 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;
}
@@ -1095,14 +1125,11 @@ static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *chip)
{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+
if (cx18_av_dbg_match(&chip->match)) {
- /*
- * Nothing else is going to claim to be this combination,
- * and the real host chip revision will be returned by a host
- * match on address 0.
- */
- chip->ident = V4L2_IDENT_CX25843;
- chip->revision = V4L2_IDENT_CX23418; /* Why not */
+ chip->ident = state->id;
+ chip->revision = state->rev;
}
return 0;
}
@@ -1143,7 +1170,7 @@ static int cx18_av_s_register(struct v4l2_subdev *sd,
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_hardware,
+ .init = cx18_av_init,
.reset = cx18_av_reset,
.queryctrl = cx18_av_queryctrl,
.g_ctrl = cx18_av_g_ctrl,
@@ -1182,19 +1209,31 @@ static const struct v4l2_subdev_ops cx18_av_ops = {
.video = &cx18_av_video_ops,
};
-int cx18_av_init(struct cx18 *cx)
+int cx18_av_probe(struct cx18 *cx, struct v4l2_subdev **sd)
{
- struct v4l2_subdev *sd = &cx->av_state.sd;
-
- v4l2_subdev_init(sd, &cx18_av_ops);
- v4l2_set_subdevdata(sd, cx);
- snprintf(sd->name, sizeof(sd->name),
- "%s-internal A/V decoder", cx->v4l2_dev.name);
- sd->grp_id = CX18_HW_CX23418;
- return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+ struct cx18_av_state *state = &cx->av_state;
+
+ state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
+ state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
+ ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
+
+ state->vid_input = CX18_AV_COMPOSITE7;
+ state->aud_input = CX18_AV_AUDIO8;
+ state->audclk_freq = 48000;
+ state->audmode = V4L2_TUNER_MODE_LANG1;
+ state->slicer_line_delay = 0;
+ state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
+
+ *sd = &state->sd;
+ v4l2_subdev_init(*sd, &cx18_av_ops);
+ v4l2_set_subdevdata(*sd, cx);
+ snprintf((*sd)->name, sizeof((*sd)->name),
+ "%s internal A/V decoder", cx->v4l2_dev.name);
+ (*sd)->grp_id = CX18_HW_CX23418;
+ return v4l2_device_register_subdev(&cx->v4l2_dev, *sd);
}
-void cx18_av_fini(struct cx18 *cx)
+void cx18_av_exit(struct cx18 *cx, struct v4l2_subdev *sd)
{
v4l2_device_unregister_subdev(&cx->av_state.sd);
}