aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Bugge <marbugge@cisco.com>2013-12-05 10:14:45 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 03:37:08 -0500
commitb82e2793476e7fd031ba9e3b0cad357d1534d1d1 (patch)
tree5b36abaed2264c80a3fef4536a8c7449dcee566d
parent245b2b678c6fc65f0265c55f7a4fa0155ad6b235 (diff)
[media] adv7842: i2c dummy clients registration
Clear i2c_clients ptr when unregistered. Warn if configured i2c-addr is zero. Signed-off-by: Martin Bugge <marbugge@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/i2c/adv7842.c83
1 files changed, 63 insertions, 20 deletions
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 2920e6b4536d..108e1b02d6c8 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -2805,8 +2805,9 @@ static const struct v4l2_ctrl_config adv7842_ctrl_free_run_color = {
2805}; 2805};
2806 2806
2807 2807
2808static void adv7842_unregister_clients(struct adv7842_state *state) 2808static void adv7842_unregister_clients(struct v4l2_subdev *sd)
2809{ 2809{
2810 struct adv7842_state *state = to_state(sd);
2810 if (state->i2c_avlink) 2811 if (state->i2c_avlink)
2811 i2c_unregister_device(state->i2c_avlink); 2812 i2c_unregister_device(state->i2c_avlink);
2812 if (state->i2c_cec) 2813 if (state->i2c_cec)
@@ -2829,15 +2830,71 @@ static void adv7842_unregister_clients(struct adv7842_state *state)
2829 i2c_unregister_device(state->i2c_cp); 2830 i2c_unregister_device(state->i2c_cp);
2830 if (state->i2c_vdp) 2831 if (state->i2c_vdp)
2831 i2c_unregister_device(state->i2c_vdp); 2832 i2c_unregister_device(state->i2c_vdp);
2833
2834 state->i2c_avlink = NULL;
2835 state->i2c_cec = NULL;
2836 state->i2c_infoframe = NULL;
2837 state->i2c_sdp_io = NULL;
2838 state->i2c_sdp = NULL;
2839 state->i2c_afe = NULL;
2840 state->i2c_repeater = NULL;
2841 state->i2c_edid = NULL;
2842 state->i2c_hdmi = NULL;
2843 state->i2c_cp = NULL;
2844 state->i2c_vdp = NULL;
2832} 2845}
2833 2846
2834static struct i2c_client *adv7842_dummy_client(struct v4l2_subdev *sd, 2847static struct i2c_client *adv7842_dummy_client(struct v4l2_subdev *sd, const char *desc,
2835 u8 addr, u8 io_reg) 2848 u8 addr, u8 io_reg)
2836{ 2849{
2837 struct i2c_client *client = v4l2_get_subdevdata(sd); 2850 struct i2c_client *client = v4l2_get_subdevdata(sd);
2851 struct i2c_client *cp;
2838 2852
2839 io_write(sd, io_reg, addr << 1); 2853 io_write(sd, io_reg, addr << 1);
2840 return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); 2854
2855 if (addr == 0) {
2856 v4l2_err(sd, "no %s i2c addr configured\n", desc);
2857 return NULL;
2858 }
2859
2860 cp = i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1);
2861 if (!cp)
2862 v4l2_err(sd, "register %s on i2c addr 0x%x failed\n", desc, addr);
2863
2864 return cp;
2865}
2866
2867static int adv7842_register_clients(struct v4l2_subdev *sd)
2868{
2869 struct adv7842_state *state = to_state(sd);
2870 struct adv7842_platform_data *pdata = &state->pdata;
2871
2872 state->i2c_avlink = adv7842_dummy_client(sd, "avlink", pdata->i2c_avlink, 0xf3);
2873 state->i2c_cec = adv7842_dummy_client(sd, "cec", pdata->i2c_cec, 0xf4);
2874 state->i2c_infoframe = adv7842_dummy_client(sd, "infoframe", pdata->i2c_infoframe, 0xf5);
2875 state->i2c_sdp_io = adv7842_dummy_client(sd, "sdp_io", pdata->i2c_sdp_io, 0xf2);
2876 state->i2c_sdp = adv7842_dummy_client(sd, "sdp", pdata->i2c_sdp, 0xf1);
2877 state->i2c_afe = adv7842_dummy_client(sd, "afe", pdata->i2c_afe, 0xf8);
2878 state->i2c_repeater = adv7842_dummy_client(sd, "repeater", pdata->i2c_repeater, 0xf9);
2879 state->i2c_edid = adv7842_dummy_client(sd, "edid", pdata->i2c_edid, 0xfa);
2880 state->i2c_hdmi = adv7842_dummy_client(sd, "hdmi", pdata->i2c_hdmi, 0xfb);
2881 state->i2c_cp = adv7842_dummy_client(sd, "cp", pdata->i2c_cp, 0xfd);
2882 state->i2c_vdp = adv7842_dummy_client(sd, "vdp", pdata->i2c_vdp, 0xfe);
2883
2884 if (!state->i2c_avlink ||
2885 !state->i2c_cec ||
2886 !state->i2c_infoframe ||
2887 !state->i2c_sdp_io ||
2888 !state->i2c_sdp ||
2889 !state->i2c_afe ||
2890 !state->i2c_repeater ||
2891 !state->i2c_edid ||
2892 !state->i2c_hdmi ||
2893 !state->i2c_cp ||
2894 !state->i2c_vdp)
2895 return -1;
2896
2897 return 0;
2841} 2898}
2842 2899
2843static int adv7842_probe(struct i2c_client *client, 2900static int adv7842_probe(struct i2c_client *client,
@@ -2939,21 +2996,7 @@ static int adv7842_probe(struct i2c_client *client,
2939 goto err_hdl; 2996 goto err_hdl;
2940 } 2997 }
2941 2998
2942 state->i2c_avlink = adv7842_dummy_client(sd, pdata->i2c_avlink, 0xf3); 2999 if (adv7842_register_clients(sd) < 0) {
2943 state->i2c_cec = adv7842_dummy_client(sd, pdata->i2c_cec, 0xf4);
2944 state->i2c_infoframe = adv7842_dummy_client(sd, pdata->i2c_infoframe, 0xf5);
2945 state->i2c_sdp_io = adv7842_dummy_client(sd, pdata->i2c_sdp_io, 0xf2);
2946 state->i2c_sdp = adv7842_dummy_client(sd, pdata->i2c_sdp, 0xf1);
2947 state->i2c_afe = adv7842_dummy_client(sd, pdata->i2c_afe, 0xf8);
2948 state->i2c_repeater = adv7842_dummy_client(sd, pdata->i2c_repeater, 0xf9);
2949 state->i2c_edid = adv7842_dummy_client(sd, pdata->i2c_edid, 0xfa);
2950 state->i2c_hdmi = adv7842_dummy_client(sd, pdata->i2c_hdmi, 0xfb);
2951 state->i2c_cp = adv7842_dummy_client(sd, pdata->i2c_cp, 0xfd);
2952 state->i2c_vdp = adv7842_dummy_client(sd, pdata->i2c_vdp, 0xfe);
2953 if (!state->i2c_avlink || !state->i2c_cec || !state->i2c_infoframe ||
2954 !state->i2c_sdp_io || !state->i2c_sdp || !state->i2c_afe ||
2955 !state->i2c_repeater || !state->i2c_edid || !state->i2c_hdmi ||
2956 !state->i2c_cp || !state->i2c_vdp) {
2957 err = -ENOMEM; 3000 err = -ENOMEM;
2958 v4l2_err(sd, "failed to create all i2c clients\n"); 3001 v4l2_err(sd, "failed to create all i2c clients\n");
2959 goto err_i2c; 3002 goto err_i2c;
@@ -2989,7 +3032,7 @@ err_work_queues:
2989 cancel_delayed_work(&state->delayed_work_enable_hotplug); 3032 cancel_delayed_work(&state->delayed_work_enable_hotplug);
2990 destroy_workqueue(state->work_queues); 3033 destroy_workqueue(state->work_queues);
2991err_i2c: 3034err_i2c:
2992 adv7842_unregister_clients(state); 3035 adv7842_unregister_clients(sd);
2993err_hdl: 3036err_hdl:
2994 v4l2_ctrl_handler_free(hdl); 3037 v4l2_ctrl_handler_free(hdl);
2995 return err; 3038 return err;
@@ -3008,7 +3051,7 @@ static int adv7842_remove(struct i2c_client *client)
3008 destroy_workqueue(state->work_queues); 3051 destroy_workqueue(state->work_queues);
3009 v4l2_device_unregister_subdev(sd); 3052 v4l2_device_unregister_subdev(sd);
3010 media_entity_cleanup(&sd->entity); 3053 media_entity_cleanup(&sd->entity);
3011 adv7842_unregister_clients(to_state(sd)); 3054 adv7842_unregister_clients(sd);
3012 v4l2_ctrl_handler_free(sd->ctrl_handler); 3055 v4l2_ctrl_handler_free(sd->ctrl_handler);
3013 return 0; 3056 return 0;
3014} 3057}