Commit fa3e70360c86480acbaa54c9791e843196327a66

Authored by Andy Walls
Committed by Mauro Carvalho Chehab
1 parent 5811cf99df

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>

Showing 12 changed files with 100 additions and 67 deletions Side-by-side Diff

drivers/media/video/cx18/cx18-av-core.c
... ... @@ -201,15 +201,45 @@
201 201 return 0;
202 202 }
203 203  
204   -static int cx18_av_init_hardware(struct v4l2_subdev *sd, u32 val)
  204 +static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
205 205 {
206 206 struct cx18_av_state *state = to_cx18_av_state(sd);
207 207 struct cx18 *cx = v4l2_get_subdevdata(sd);
208 208  
209   - if (!state->is_initialized) {
210   - /* initialize on first use */
211   - state->is_initialized = 1;
212   - cx18_av_initialize(cx);
  209 + switch (val) {
  210 + case CX18_AV_INIT_PLLS:
  211 + /*
  212 + * The crystal freq used in calculations in this driver will be
  213 + * 28.636360 MHz.
  214 + * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
  215 + */
  216 +
  217 + /*
  218 + * VDCLK Integer = 0x0f, Post Divider = 0x04
  219 + * AIMCLK Integer = 0x0e, Post Divider = 0x16
  220 + */
  221 + cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
  222 +
  223 + /* VDCLK Fraction = 0x2be2fe */
  224 + /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
  225 + cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
  226 +
  227 + /* AIMCLK Fraction = 0x05227ad */
  228 + /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
  229 + cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
  230 +
  231 + /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
  232 + cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
  233 + break;
  234 +
  235 + case CX18_AV_INIT_NORMAL:
  236 + default:
  237 + if (!state->is_initialized) {
  238 + /* initialize on first use */
  239 + state->is_initialized = 1;
  240 + cx18_av_initialize(cx);
  241 + }
  242 + break;
213 243 }
214 244 return 0;
215 245 }
216 246  
... ... @@ -1095,14 +1125,11 @@
1095 1125 static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
1096 1126 struct v4l2_dbg_chip_ident *chip)
1097 1127 {
  1128 + struct cx18_av_state *state = to_cx18_av_state(sd);
  1129 +
1098 1130 if (cx18_av_dbg_match(&chip->match)) {
1099   - /*
1100   - * Nothing else is going to claim to be this combination,
1101   - * and the real host chip revision will be returned by a host
1102   - * match on address 0.
1103   - */
1104   - chip->ident = V4L2_IDENT_CX25843;
1105   - chip->revision = V4L2_IDENT_CX23418; /* Why not */
  1131 + chip->ident = state->id;
  1132 + chip->revision = state->rev;
1106 1133 }
1107 1134 return 0;
1108 1135 }
... ... @@ -1143,7 +1170,7 @@
1143 1170 static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1144 1171 .g_chip_ident = cx18_av_g_chip_ident,
1145 1172 .log_status = cx18_av_log_status,
1146   - .init = cx18_av_init_hardware,
  1173 + .init = cx18_av_init,
1147 1174 .reset = cx18_av_reset,
1148 1175 .queryctrl = cx18_av_queryctrl,
1149 1176 .g_ctrl = cx18_av_g_ctrl,
1150 1177  
1151 1178  
1152 1179  
... ... @@ -1182,19 +1209,31 @@
1182 1209 .video = &cx18_av_video_ops,
1183 1210 };
1184 1211  
1185   -int cx18_av_init(struct cx18 *cx)
  1212 +int cx18_av_probe(struct cx18 *cx, struct v4l2_subdev **sd)
1186 1213 {
1187   - struct v4l2_subdev *sd = &cx->av_state.sd;
  1214 + struct cx18_av_state *state = &cx->av_state;
1188 1215  
1189   - v4l2_subdev_init(sd, &cx18_av_ops);
1190   - v4l2_set_subdevdata(sd, cx);
1191   - snprintf(sd->name, sizeof(sd->name),
1192   - "%s-internal A/V decoder", cx->v4l2_dev.name);
1193   - sd->grp_id = CX18_HW_CX23418;
1194   - return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
  1216 + state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
  1217 + state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
  1218 + ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
  1219 +
  1220 + state->vid_input = CX18_AV_COMPOSITE7;
  1221 + state->aud_input = CX18_AV_AUDIO8;
  1222 + state->audclk_freq = 48000;
  1223 + state->audmode = V4L2_TUNER_MODE_LANG1;
  1224 + state->slicer_line_delay = 0;
  1225 + state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
  1226 +
  1227 + *sd = &state->sd;
  1228 + v4l2_subdev_init(*sd, &cx18_av_ops);
  1229 + v4l2_set_subdevdata(*sd, cx);
  1230 + snprintf((*sd)->name, sizeof((*sd)->name),
  1231 + "%s internal A/V decoder", cx->v4l2_dev.name);
  1232 + (*sd)->grp_id = CX18_HW_CX23418;
  1233 + return v4l2_device_register_subdev(&cx->v4l2_dev, *sd);
1195 1234 }
1196 1235  
1197   -void cx18_av_fini(struct cx18 *cx)
  1236 +void cx18_av_exit(struct cx18 *cx, struct v4l2_subdev *sd)
1198 1237 {
1199 1238 v4l2_device_unregister_subdev(&cx->av_state.sd);
1200 1239 }
drivers/media/video/cx18/cx18-av-core.h
... ... @@ -323,6 +323,11 @@
323 323 return container_of(sd, struct cx18_av_state, sd);
324 324 }
325 325  
  326 +enum cx18_av_subdev_init_arg {
  327 + CX18_AV_INIT_NORMAL = 0,
  328 + CX18_AV_INIT_PLLS = 1,
  329 +};
  330 +
326 331 /* ----------------------------------------------------------------------- */
327 332 /* cx18_av-core.c */
328 333 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
... ... @@ -337,9 +342,8 @@
337 342 int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
338 343 void cx18_av_std_setup(struct cx18 *cx);
339 344  
340   -int cx18_av_cmd(struct cx18 *cx, int cmd, void *arg); /* FIXME - Remove */
341   -int cx18_av_init(struct cx18 *cx);
342   -void cx18_av_fini(struct cx18 *cx);
  345 +int cx18_av_probe(struct cx18 *cx, struct v4l2_subdev **sd);
  346 +void cx18_av_exit(struct cx18 *cx, struct v4l2_subdev *sd);
343 347  
344 348 /* ----------------------------------------------------------------------- */
345 349 /* cx18_av-firmware.c */
drivers/media/video/cx18/cx18-controls.c
... ... @@ -67,7 +67,7 @@
67 67 case V4L2_CID_HUE:
68 68 case V4L2_CID_SATURATION:
69 69 case V4L2_CID_CONTRAST:
70   - if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl))
  70 + if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
71 71 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
72 72 return 0;
73 73  
... ... @@ -126,7 +126,7 @@
126 126 case V4L2_CID_HUE:
127 127 case V4L2_CID_SATURATION:
128 128 case V4L2_CID_CONTRAST:
129   - return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl);
  129 + return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
130 130  
131 131 case V4L2_CID_AUDIO_VOLUME:
132 132 case V4L2_CID_AUDIO_MUTE:
... ... @@ -151,7 +151,7 @@
151 151 case V4L2_CID_HUE:
152 152 case V4L2_CID_SATURATION:
153 153 case V4L2_CID_CONTRAST:
154   - return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl);
  154 + return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
155 155  
156 156 case V4L2_CID_AUDIO_VOLUME:
157 157 case V4L2_CID_AUDIO_MUTE:
... ... @@ -278,7 +278,7 @@
278 278 fmt.fmt.pix.width = cx->params.width
279 279 / (is_mpeg1 ? 2 : 1);
280 280 fmt.fmt.pix.height = cx->params.height;
281   - cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
  281 + v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt);
282 282 }
283 283 priv.cx = cx;
284 284 priv.s = &cx->streams[id->type];
drivers/media/video/cx18/cx18-driver.c
... ... @@ -621,13 +621,6 @@
621 621 i = 0;
622 622 cx->active_input = i;
623 623 cx->audio_input = cx->card->video_inputs[i].audio_index;
624   - cx->av_state.vid_input = CX18_AV_COMPOSITE7;
625   - cx->av_state.aud_input = CX18_AV_AUDIO8;
626   - cx->av_state.audclk_freq = 48000;
627   - cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
628   - cx->av_state.slicer_line_delay = 0;
629   - cx->av_state.slicer_line_offset =
630   - (10 + cx->av_state.slicer_line_delay - 2);
631 624 }
632 625  
633 626 static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
... ... @@ -812,6 +805,14 @@
812 805  
813 806 cx18_gpio_init(cx);
814 807  
  808 + retval = cx18_av_probe(cx, &cx->sd_av);
  809 + if (retval) {
  810 + CX18_ERR("Could not register A/V decoder subdevice\n");
  811 + goto free_map;
  812 + }
  813 + /* Initialize the A/V decoder PLLs to sane defaults */
  814 + v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_PLLS);
  815 +
815 816 /* active i2c */
816 817 CX18_DEBUG_INFO("activating i2c...\n");
817 818 retval = init_cx18_i2c(cx);
... ... @@ -1019,6 +1020,9 @@
1019 1020 cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
1020 1021 cx18_vapi(cx, CX18_APU_RESETAI, 0);
1021 1022 cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
  1023 +
  1024 + /* Init the A/V decoder, if it hasn't been already */
  1025 + v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL);
1022 1026  
1023 1027 vf.tuner = 0;
1024 1028 vf.type = V4L2_TUNER_ANALOG_TV;
drivers/media/video/cx18/cx18-driver.h
... ... @@ -448,6 +448,7 @@
448 448 int instance;
449 449 struct pci_dev *pci_dev;
450 450 struct v4l2_device v4l2_dev;
  451 + struct v4l2_subdev *sd_av;
451 452  
452 453 const struct cx18_card *card; /* card information */
453 454 const char *card_name; /* full name of the card */
drivers/media/video/cx18/cx18-firmware.c
... ... @@ -26,7 +26,6 @@
26 26 #include "cx18-irq.h"
27 27 #include "cx18-firmware.h"
28 28 #include "cx18-cards.h"
29   -#include "cx18-av-core.h"
30 29 #include <linux/firmware.h>
31 30  
32 31 #define CX18_PROC_SOFT_RESET 0xc70010
... ... @@ -285,23 +284,6 @@
285 284 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
286 285 cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
287 286 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
288   -
289   - /*
290   - * VDCLK Integer = 0x0f, Post Divider = 0x04
291   - * AIMCLK Integer = 0x0e, Post Divider = 0x16
292   - */
293   - cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
294   -
295   - /* VDCLK Fraction = 0x2be2fe */
296   - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
297   - cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
298   -
299   - /* AIMCLK Fraction = 0x05227ad */
300   - /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */
301   - cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
302   -
303   - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
304   - cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
305 287  
306 288 /* Defaults */
307 289 /* APU = SC or SC/2 = 125/62.5 */
drivers/media/video/cx18/cx18-i2c.c
... ... @@ -304,7 +304,7 @@
304 304 return cx18_gpio(cx, cmd, arg);
305 305  
306 306 if (hw == CX18_HW_CX23418)
307   - return cx18_av_cmd(cx, cmd, arg);
  307 + return v4l2_subdev_command(cx->sd_av, cmd, arg);
308 308  
309 309 addr = cx18_i2c_hw_addr(cx, hw);
310 310 if (addr < 0) {
... ... @@ -322,7 +322,7 @@
322 322 CX18_ERR("adapter is not set\n");
323 323 return;
324 324 }
325   - cx18_av_cmd(cx, cmd, arg);
  325 + v4l2_subdev_command(cx->sd_av, cmd, arg);
326 326 i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
327 327 i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
328 328 if (cx->hw_flags & CX18_HW_GPIO)
drivers/media/video/cx18/cx18-ioctl.c
... ... @@ -208,7 +208,7 @@
208 208 * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
209 209 * fmt->fmt.sliced under valid calling conditions
210 210 */
211   - if (cx18_av_cmd(cx, VIDIOC_G_FMT, fmt))
  211 + if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt))
212 212 return -EINVAL;
213 213  
214 214 /* Ensure V4L2 spec compliant output */
... ... @@ -295,7 +295,7 @@
295 295  
296 296 cx->params.width = w;
297 297 cx->params.height = h;
298   - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
  298 + v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
299 299 return cx18_g_fmt_vid_cap(file, fh, fmt);
300 300 }
301 301  
... ... @@ -322,7 +322,7 @@
322 322 * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
323 323 * calling conditions
324 324 */
325   - ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
  325 + ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
326 326 if (ret)
327 327 return ret;
328 328  
... ... @@ -359,7 +359,7 @@
359 359 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
360 360 * passed in fmt->fmt.sliced under valid calling conditions
361 361 */
362   - ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
  362 + ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
363 363 if (ret)
364 364 return ret;
365 365 /* Store our current v4l2 sliced VBI settings */
... ... @@ -516,7 +516,8 @@
516 516  
517 517 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
518 518 return -EINVAL;
519   - return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
  519 + CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
  520 + return -EINVAL;
520 521 }
521 522  
522 523 static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
... ... @@ -525,7 +526,8 @@
525 526  
526 527 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
527 528 return -EINVAL;
528   - return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
  529 + CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
  530 + return -EINVAL;
529 531 }
530 532  
531 533 static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
drivers/media/video/cx18/cx18-streams.c
... ... @@ -348,7 +348,7 @@
348 348 }
349 349  
350 350 /* setup VBI registers */
351   - cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
  351 + v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in);
352 352  
353 353 /*
354 354 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
drivers/media/video/cx18/cx18-vbi.c
... ... @@ -154,7 +154,7 @@
154 154 if (p[0] != 0xff || p[1] || p[2] || p[3] != eav)
155 155 continue;
156 156 vbi.p = p + 4;
157   - cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
  157 + v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi);
158 158 if (vbi.type) {
159 159 cx->vbi.sliced_data[line].id = vbi.type;
160 160 cx->vbi.sliced_data[line].field = vbi.is_second_field;
drivers/media/video/cx18/cx18-video.c
... ... @@ -32,7 +32,7 @@
32 32  
33 33 route.input = cx->card->video_inputs[inp].video_input;
34 34 route.output = 0;
35   - cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route);
  35 + v4l2_subdev_call(cx->sd_av, video, s_routing, &route);
36 36  
37 37 type = cx->card->video_inputs[inp].video_type;
38 38  
include/media/v4l2-chip-ident.h
... ... @@ -64,7 +64,8 @@
64 64 /* module saa7146: reserved range 300-309 */
65 65 V4L2_IDENT_SAA7146 = 300,
66 66  
67   - /* Conexant MPEG encoder/decoders: reserved range 410-420 */
  67 + /* Conexant MPEG encoder/decoders: reserved range 400-420 */
  68 + V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
68 69 V4L2_IDENT_CX23415 = 415,
69 70 V4L2_IDENT_CX23416 = 416,
70 71 V4L2_IDENT_CX23418 = 418,