diff options
author | Federico Vaga <federico.vaga@gmail.com> | 2012-07-11 10:29:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-07-30 19:22:34 -0400 |
commit | c9fbedddc2b9cdf1b1a4a4053f52a629c0daa9a0 (patch) | |
tree | 56c15521a36b2b756071568fdd13fc5da2e14060 /drivers/media/video/adv7180.c | |
parent | 16d18b16ace670641de74e6fe8005029b4057559 (diff) |
[media] adv7180.c: convert to v4l2 control framework
[mchehab@redhat.com: fix checkpatch.pl ERROR:
Macros with complex values should be enclosed in parenthesis]
Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/adv7180.c')
-rw-r--r-- | drivers/media/video/adv7180.c | 235 |
1 files changed, 84 insertions, 151 deletions
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index 174bffacf117..45ecf8db1eae 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c | |||
@@ -26,11 +26,10 @@ | |||
26 | #include <media/v4l2-ioctl.h> | 26 | #include <media/v4l2-ioctl.h> |
27 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
28 | #include <media/v4l2-device.h> | 28 | #include <media/v4l2-device.h> |
29 | #include <media/v4l2-ctrls.h> | ||
29 | #include <media/v4l2-chip-ident.h> | 30 | #include <media/v4l2-chip-ident.h> |
30 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
31 | 32 | ||
32 | #define DRIVER_NAME "adv7180" | ||
33 | |||
34 | #define ADV7180_INPUT_CONTROL_REG 0x00 | 33 | #define ADV7180_INPUT_CONTROL_REG 0x00 |
35 | #define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00 | 34 | #define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00 |
36 | #define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10 | 35 | #define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10 |
@@ -55,21 +54,21 @@ | |||
55 | 54 | ||
56 | #define ADV7180_AUTODETECT_ENABLE_REG 0x07 | 55 | #define ADV7180_AUTODETECT_ENABLE_REG 0x07 |
57 | #define ADV7180_AUTODETECT_DEFAULT 0x7f | 56 | #define ADV7180_AUTODETECT_DEFAULT 0x7f |
58 | 57 | /* Contrast */ | |
59 | #define ADV7180_CON_REG 0x08 /*Unsigned */ | 58 | #define ADV7180_CON_REG 0x08 /*Unsigned */ |
60 | #define CON_REG_MIN 0 | 59 | #define ADV7180_CON_MIN 0 |
61 | #define CON_REG_DEF 128 | 60 | #define ADV7180_CON_DEF 128 |
62 | #define CON_REG_MAX 255 | 61 | #define ADV7180_CON_MAX 255 |
63 | 62 | /* Brightness*/ | |
64 | #define ADV7180_BRI_REG 0x0a /*Signed */ | 63 | #define ADV7180_BRI_REG 0x0a /*Signed */ |
65 | #define BRI_REG_MIN -128 | 64 | #define ADV7180_BRI_MIN -128 |
66 | #define BRI_REG_DEF 0 | 65 | #define ADV7180_BRI_DEF 0 |
67 | #define BRI_REG_MAX 127 | 66 | #define ADV7180_BRI_MAX 127 |
68 | 67 | /* Hue */ | |
69 | #define ADV7180_HUE_REG 0x0b /*Signed, inverted */ | 68 | #define ADV7180_HUE_REG 0x0b /*Signed, inverted */ |
70 | #define HUE_REG_MIN -127 | 69 | #define ADV7180_HUE_MIN -127 |
71 | #define HUE_REG_DEF 0 | 70 | #define ADV7180_HUE_DEF 0 |
72 | #define HUE_REG_MAX 128 | 71 | #define ADV7180_HUE_MAX 128 |
73 | 72 | ||
74 | #define ADV7180_ADI_CTRL_REG 0x0e | 73 | #define ADV7180_ADI_CTRL_REG 0x0e |
75 | #define ADV7180_ADI_CTRL_IRQ_SPACE 0x20 | 74 | #define ADV7180_ADI_CTRL_IRQ_SPACE 0x20 |
@@ -98,12 +97,12 @@ | |||
98 | #define ADV7180_ICONF1_ACTIVE_LOW 0x01 | 97 | #define ADV7180_ICONF1_ACTIVE_LOW 0x01 |
99 | #define ADV7180_ICONF1_PSYNC_ONLY 0x10 | 98 | #define ADV7180_ICONF1_PSYNC_ONLY 0x10 |
100 | #define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0 | 99 | #define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0 |
101 | 100 | /* Saturation */ | |
102 | #define ADV7180_SD_SAT_CB_REG 0xe3 /*Unsigned */ | 101 | #define ADV7180_SD_SAT_CB_REG 0xe3 /*Unsigned */ |
103 | #define ADV7180_SD_SAT_CR_REG 0xe4 /*Unsigned */ | 102 | #define ADV7180_SD_SAT_CR_REG 0xe4 /*Unsigned */ |
104 | #define SAT_REG_MIN 0 | 103 | #define ADV7180_SAT_MIN 0 |
105 | #define SAT_REG_DEF 128 | 104 | #define ADV7180_SAT_DEF 128 |
106 | #define SAT_REG_MAX 255 | 105 | #define ADV7180_SAT_MAX 255 |
107 | 106 | ||
108 | #define ADV7180_IRQ1_LOCK 0x01 | 107 | #define ADV7180_IRQ1_LOCK 0x01 |
109 | #define ADV7180_IRQ1_UNLOCK 0x02 | 108 | #define ADV7180_IRQ1_UNLOCK 0x02 |
@@ -121,18 +120,18 @@ | |||
121 | #define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F | 120 | #define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F |
122 | 121 | ||
123 | struct adv7180_state { | 122 | struct adv7180_state { |
123 | struct v4l2_ctrl_handler ctrl_hdl; | ||
124 | struct v4l2_subdev sd; | 124 | struct v4l2_subdev sd; |
125 | struct work_struct work; | 125 | struct work_struct work; |
126 | struct mutex mutex; /* mutual excl. when accessing chip */ | 126 | struct mutex mutex; /* mutual excl. when accessing chip */ |
127 | int irq; | 127 | int irq; |
128 | v4l2_std_id curr_norm; | 128 | v4l2_std_id curr_norm; |
129 | bool autodetect; | 129 | bool autodetect; |
130 | s8 brightness; | ||
131 | s16 hue; | ||
132 | u8 contrast; | ||
133 | u8 saturation; | ||
134 | u8 input; | 130 | u8 input; |
135 | }; | 131 | }; |
132 | #define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \ | ||
133 | struct adv7180_state, \ | ||
134 | ctrl_hdl)->sd) | ||
136 | 135 | ||
137 | static v4l2_std_id adv7180_std_to_v4l2(u8 status1) | 136 | static v4l2_std_id adv7180_std_to_v4l2(u8 status1) |
138 | { | 137 | { |
@@ -237,7 +236,7 @@ static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input, | |||
237 | if (ret) | 236 | if (ret) |
238 | return ret; | 237 | return ret; |
239 | 238 | ||
240 | /*We cannot discriminate between LQFP and 40-pin LFCSP, so accept | 239 | /* We cannot discriminate between LQFP and 40-pin LFCSP, so accept |
241 | * all inputs and let the card driver take care of validation | 240 | * all inputs and let the card driver take care of validation |
242 | */ | 241 | */ |
243 | if ((input & ADV7180_INPUT_CONTROL_INSEL_MASK) != input) | 242 | if ((input & ADV7180_INPUT_CONTROL_INSEL_MASK) != input) |
@@ -316,117 +315,39 @@ out: | |||
316 | return ret; | 315 | return ret; |
317 | } | 316 | } |
318 | 317 | ||
319 | static int adv7180_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | 318 | static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl) |
320 | { | ||
321 | switch (qc->id) { | ||
322 | case V4L2_CID_BRIGHTNESS: | ||
323 | return v4l2_ctrl_query_fill(qc, BRI_REG_MIN, BRI_REG_MAX, | ||
324 | 1, BRI_REG_DEF); | ||
325 | case V4L2_CID_HUE: | ||
326 | return v4l2_ctrl_query_fill(qc, HUE_REG_MIN, HUE_REG_MAX, | ||
327 | 1, HUE_REG_DEF); | ||
328 | case V4L2_CID_CONTRAST: | ||
329 | return v4l2_ctrl_query_fill(qc, CON_REG_MIN, CON_REG_MAX, | ||
330 | 1, CON_REG_DEF); | ||
331 | case V4L2_CID_SATURATION: | ||
332 | return v4l2_ctrl_query_fill(qc, SAT_REG_MIN, SAT_REG_MAX, | ||
333 | 1, SAT_REG_DEF); | ||
334 | default: | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | return -EINVAL; | ||
339 | } | ||
340 | |||
341 | static int adv7180_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
342 | { | ||
343 | struct adv7180_state *state = to_state(sd); | ||
344 | int ret = mutex_lock_interruptible(&state->mutex); | ||
345 | if (ret) | ||
346 | return ret; | ||
347 | |||
348 | switch (ctrl->id) { | ||
349 | case V4L2_CID_BRIGHTNESS: | ||
350 | ctrl->value = state->brightness; | ||
351 | break; | ||
352 | case V4L2_CID_HUE: | ||
353 | ctrl->value = state->hue; | ||
354 | break; | ||
355 | case V4L2_CID_CONTRAST: | ||
356 | ctrl->value = state->contrast; | ||
357 | break; | ||
358 | case V4L2_CID_SATURATION: | ||
359 | ctrl->value = state->saturation; | ||
360 | break; | ||
361 | default: | ||
362 | ret = -EINVAL; | ||
363 | } | ||
364 | |||
365 | mutex_unlock(&state->mutex); | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | static int adv7180_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
370 | { | 319 | { |
320 | struct v4l2_subdev *sd = to_adv7180_sd(ctrl); | ||
371 | struct adv7180_state *state = to_state(sd); | 321 | struct adv7180_state *state = to_state(sd); |
372 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 322 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
373 | int ret = mutex_lock_interruptible(&state->mutex); | 323 | int ret = mutex_lock_interruptible(&state->mutex); |
324 | int val; | ||
325 | |||
374 | if (ret) | 326 | if (ret) |
375 | return ret; | 327 | return ret; |
376 | 328 | val = ctrl->val; | |
377 | switch (ctrl->id) { | 329 | switch (ctrl->id) { |
378 | case V4L2_CID_BRIGHTNESS: | 330 | case V4L2_CID_BRIGHTNESS: |
379 | if ((ctrl->value > BRI_REG_MAX) | 331 | ret = i2c_smbus_write_byte_data(client, ADV7180_BRI_REG, val); |
380 | || (ctrl->value < BRI_REG_MIN)) { | ||
381 | ret = -ERANGE; | ||
382 | break; | ||
383 | } | ||
384 | state->brightness = ctrl->value; | ||
385 | ret = i2c_smbus_write_byte_data(client, | ||
386 | ADV7180_BRI_REG, | ||
387 | state->brightness); | ||
388 | break; | 332 | break; |
389 | case V4L2_CID_HUE: | 333 | case V4L2_CID_HUE: |
390 | if ((ctrl->value > HUE_REG_MAX) | ||
391 | || (ctrl->value < HUE_REG_MIN)) { | ||
392 | ret = -ERANGE; | ||
393 | break; | ||
394 | } | ||
395 | state->hue = ctrl->value; | ||
396 | /*Hue is inverted according to HSL chart */ | 334 | /*Hue is inverted according to HSL chart */ |
397 | ret = i2c_smbus_write_byte_data(client, | 335 | ret = i2c_smbus_write_byte_data(client, ADV7180_HUE_REG, -val); |
398 | ADV7180_HUE_REG, -state->hue); | ||
399 | break; | 336 | break; |
400 | case V4L2_CID_CONTRAST: | 337 | case V4L2_CID_CONTRAST: |
401 | if ((ctrl->value > CON_REG_MAX) | 338 | ret = i2c_smbus_write_byte_data(client, ADV7180_CON_REG, val); |
402 | || (ctrl->value < CON_REG_MIN)) { | ||
403 | ret = -ERANGE; | ||
404 | break; | ||
405 | } | ||
406 | state->contrast = ctrl->value; | ||
407 | ret = i2c_smbus_write_byte_data(client, | ||
408 | ADV7180_CON_REG, | ||
409 | state->contrast); | ||
410 | break; | 339 | break; |
411 | case V4L2_CID_SATURATION: | 340 | case V4L2_CID_SATURATION: |
412 | if ((ctrl->value > SAT_REG_MAX) | ||
413 | || (ctrl->value < SAT_REG_MIN)) { | ||
414 | ret = -ERANGE; | ||
415 | break; | ||
416 | } | ||
417 | /* | 341 | /* |
418 | *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE | 342 | *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE |
419 | *Let's not confuse the user, everybody understands saturation | 343 | *Let's not confuse the user, everybody understands saturation |
420 | */ | 344 | */ |
421 | state->saturation = ctrl->value; | 345 | ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CB_REG, |
422 | ret = i2c_smbus_write_byte_data(client, | 346 | val); |
423 | ADV7180_SD_SAT_CB_REG, | ||
424 | state->saturation); | ||
425 | if (ret < 0) | 347 | if (ret < 0) |
426 | break; | 348 | break; |
427 | ret = i2c_smbus_write_byte_data(client, | 349 | ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CR_REG, |
428 | ADV7180_SD_SAT_CR_REG, | 350 | val); |
429 | state->saturation); | ||
430 | break; | 351 | break; |
431 | default: | 352 | default: |
432 | ret = -EINVAL; | 353 | ret = -EINVAL; |
@@ -436,6 +357,42 @@ static int adv7180_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
436 | return ret; | 357 | return ret; |
437 | } | 358 | } |
438 | 359 | ||
360 | static const struct v4l2_ctrl_ops adv7180_ctrl_ops = { | ||
361 | .s_ctrl = adv7180_s_ctrl, | ||
362 | }; | ||
363 | |||
364 | static int adv7180_init_controls(struct adv7180_state *state) | ||
365 | { | ||
366 | v4l2_ctrl_handler_init(&state->ctrl_hdl, 4); | ||
367 | |||
368 | v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops, | ||
369 | V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN, | ||
370 | ADV7180_BRI_MAX, 1, ADV7180_BRI_DEF); | ||
371 | v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops, | ||
372 | V4L2_CID_CONTRAST, ADV7180_CON_MIN, | ||
373 | ADV7180_CON_MAX, 1, ADV7180_CON_DEF); | ||
374 | v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops, | ||
375 | V4L2_CID_SATURATION, ADV7180_SAT_MIN, | ||
376 | ADV7180_SAT_MAX, 1, ADV7180_SAT_DEF); | ||
377 | v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops, | ||
378 | V4L2_CID_HUE, ADV7180_HUE_MIN, | ||
379 | ADV7180_HUE_MAX, 1, ADV7180_HUE_DEF); | ||
380 | state->sd.ctrl_handler = &state->ctrl_hdl; | ||
381 | if (state->ctrl_hdl.error) { | ||
382 | int err = state->ctrl_hdl.error; | ||
383 | |||
384 | v4l2_ctrl_handler_free(&state->ctrl_hdl); | ||
385 | return err; | ||
386 | } | ||
387 | v4l2_ctrl_handler_setup(&state->ctrl_hdl); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | static void adv7180_exit_controls(struct adv7180_state *state) | ||
392 | { | ||
393 | v4l2_ctrl_handler_free(&state->ctrl_hdl); | ||
394 | } | ||
395 | |||
439 | static const struct v4l2_subdev_video_ops adv7180_video_ops = { | 396 | static const struct v4l2_subdev_video_ops adv7180_video_ops = { |
440 | .querystd = adv7180_querystd, | 397 | .querystd = adv7180_querystd, |
441 | .g_input_status = adv7180_g_input_status, | 398 | .g_input_status = adv7180_g_input_status, |
@@ -445,9 +402,9 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { | |||
445 | static const struct v4l2_subdev_core_ops adv7180_core_ops = { | 402 | static const struct v4l2_subdev_core_ops adv7180_core_ops = { |
446 | .g_chip_ident = adv7180_g_chip_ident, | 403 | .g_chip_ident = adv7180_g_chip_ident, |
447 | .s_std = adv7180_s_std, | 404 | .s_std = adv7180_s_std, |
448 | .queryctrl = adv7180_queryctrl, | 405 | .queryctrl = v4l2_subdev_queryctrl, |
449 | .g_ctrl = adv7180_g_ctrl, | 406 | .g_ctrl = v4l2_subdev_g_ctrl, |
450 | .s_ctrl = adv7180_s_ctrl, | 407 | .s_ctrl = v4l2_subdev_s_ctrl, |
451 | }; | 408 | }; |
452 | 409 | ||
453 | static const struct v4l2_subdev_ops adv7180_ops = { | 410 | static const struct v4l2_subdev_ops adv7180_ops = { |
@@ -539,7 +496,7 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state) | |||
539 | 496 | ||
540 | /* register for interrupts */ | 497 | /* register for interrupts */ |
541 | if (state->irq > 0) { | 498 | if (state->irq > 0) { |
542 | ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME, | 499 | ret = request_irq(state->irq, adv7180_irq, 0, KBUILD_MODNAME, |
543 | state); | 500 | state); |
544 | if (ret) | 501 | if (ret) |
545 | return ret; | 502 | return ret; |
@@ -580,31 +537,6 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state) | |||
580 | return ret; | 537 | return ret; |
581 | } | 538 | } |
582 | 539 | ||
583 | /*Set default value for controls */ | ||
584 | ret = i2c_smbus_write_byte_data(client, ADV7180_BRI_REG, | ||
585 | state->brightness); | ||
586 | if (ret < 0) | ||
587 | return ret; | ||
588 | |||
589 | ret = i2c_smbus_write_byte_data(client, ADV7180_HUE_REG, state->hue); | ||
590 | if (ret < 0) | ||
591 | return ret; | ||
592 | |||
593 | ret = i2c_smbus_write_byte_data(client, ADV7180_CON_REG, | ||
594 | state->contrast); | ||
595 | if (ret < 0) | ||
596 | return ret; | ||
597 | |||
598 | ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CB_REG, | ||
599 | state->saturation); | ||
600 | if (ret < 0) | ||
601 | return ret; | ||
602 | |||
603 | ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CR_REG, | ||
604 | state->saturation); | ||
605 | if (ret < 0) | ||
606 | return ret; | ||
607 | |||
608 | return 0; | 540 | return 0; |
609 | } | 541 | } |
610 | 542 | ||
@@ -632,25 +564,26 @@ static __devinit int adv7180_probe(struct i2c_client *client, | |||
632 | INIT_WORK(&state->work, adv7180_work); | 564 | INIT_WORK(&state->work, adv7180_work); |
633 | mutex_init(&state->mutex); | 565 | mutex_init(&state->mutex); |
634 | state->autodetect = true; | 566 | state->autodetect = true; |
635 | state->brightness = BRI_REG_DEF; | ||
636 | state->hue = HUE_REG_DEF; | ||
637 | state->contrast = CON_REG_DEF; | ||
638 | state->saturation = SAT_REG_DEF; | ||
639 | state->input = 0; | 567 | state->input = 0; |
640 | sd = &state->sd; | 568 | sd = &state->sd; |
641 | v4l2_i2c_subdev_init(sd, client, &adv7180_ops); | 569 | v4l2_i2c_subdev_init(sd, client, &adv7180_ops); |
642 | 570 | ||
643 | ret = init_device(client, state); | 571 | ret = adv7180_init_controls(state); |
644 | if (0 != ret) | 572 | if (ret) |
645 | goto err_unreg_subdev; | 573 | goto err_unreg_subdev; |
574 | ret = init_device(client, state); | ||
575 | if (ret) | ||
576 | goto err_free_ctrl; | ||
646 | return 0; | 577 | return 0; |
647 | 578 | ||
579 | err_free_ctrl: | ||
580 | adv7180_exit_controls(state); | ||
648 | err_unreg_subdev: | 581 | err_unreg_subdev: |
649 | mutex_destroy(&state->mutex); | 582 | mutex_destroy(&state->mutex); |
650 | v4l2_device_unregister_subdev(sd); | 583 | v4l2_device_unregister_subdev(sd); |
651 | kfree(state); | 584 | kfree(state); |
652 | err: | 585 | err: |
653 | printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret); | 586 | printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret); |
654 | return ret; | 587 | return ret; |
655 | } | 588 | } |
656 | 589 | ||
@@ -678,7 +611,7 @@ static __devexit int adv7180_remove(struct i2c_client *client) | |||
678 | } | 611 | } |
679 | 612 | ||
680 | static const struct i2c_device_id adv7180_id[] = { | 613 | static const struct i2c_device_id adv7180_id[] = { |
681 | {DRIVER_NAME, 0}, | 614 | {KBUILD_MODNAME, 0}, |
682 | {}, | 615 | {}, |
683 | }; | 616 | }; |
684 | 617 | ||
@@ -716,7 +649,7 @@ MODULE_DEVICE_TABLE(i2c, adv7180_id); | |||
716 | static struct i2c_driver adv7180_driver = { | 649 | static struct i2c_driver adv7180_driver = { |
717 | .driver = { | 650 | .driver = { |
718 | .owner = THIS_MODULE, | 651 | .owner = THIS_MODULE, |
719 | .name = DRIVER_NAME, | 652 | .name = KBUILD_MODNAME, |
720 | }, | 653 | }, |
721 | .probe = adv7180_probe, | 654 | .probe = adv7180_probe, |
722 | .remove = __devexit_p(adv7180_remove), | 655 | .remove = __devexit_p(adv7180_remove), |